Files
subconverter-go/internal/conversion/response.go
Rogee 7fcabe0225
Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
first commit
2025-09-28 10:05:07 +08:00

399 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package conversion
import (
"encoding/json"
"fmt"
"time"
)
// ConversionResponse 表示转换响应的结果
// 该结构体包含转换操作的结果和元数据
type ConversionResponse struct {
// 基本状态
Success bool `json:"success"` // 转换是否成功
// 内容字段
Content string `json:"content,omitempty"` // 转换后的配置内容
ContentType string `json:"content_type,omitempty"` // 内容类型
// 错误信息
Error string `json:"error,omitempty"` // 错误消息
ErrorCode string `json:"error_code,omitempty"` // 错误代码
ErrorDetail string `json:"error_detail,omitempty"` // 详细错误信息
// 元数据
Timestamp time.Time `json:"timestamp"` // 处理时间戳
ProcessingTime int64 `json:"processing_time_ms"` // 处理时间(毫秒)
TargetFormat string `json:"target_format,omitempty"` // 目标格式
SourceURL string `json:"source_url,omitempty"` // 源URL
ConfigURL string `json:"config_url,omitempty"` // 配置URL
// 统计信息
NodeCount int `json:"node_count,omitempty"` // 节点数量
FilteredCount int `json:"filtered_count,omitempty"` // 过滤后的节点数量
ProxyTypes []string `json:"proxy_types,omitempty"` // 代理类型列表
// 响应头信息
Headers map[string]string `json:"headers,omitempty"` // 自定义响应头
ContentLength int64 `json:"content_length,omitempty"` // 内容长度
ETag string `json:"etag,omitempty"` // ETag标识
CacheControl string `json:"cache_control,omitempty"` // 缓存控制
// 调试信息
DebugInfo map[string]interface{} `json:"debug_info,omitempty"` // 调试信息
RequestID string `json:"request_id,omitempty"` // 请求ID
ServerInfo string `json:"server_info,omitempty"` // 服务器信息
}
// NewConversionResponse 创建新的成功响应
// 返回包含基本成功信息的ConversionResponse
func NewConversionResponse() *ConversionResponse {
return &ConversionResponse{
Success: true,
Timestamp: time.Now(),
ProcessingTime: 0,
Headers: make(map[string]string),
DebugInfo: make(map[string]interface{}),
}
}
// NewErrorResponse 创建新的错误响应
// 根据错误信息创建错误响应
func NewErrorResponse(message string) *ConversionResponse {
return &ConversionResponse{
Success: false,
Error: message,
ErrorCode: "CONVERSION_ERROR",
Timestamp: time.Now(),
Headers: make(map[string]string),
DebugInfo: make(map[string]interface{}),
}
}
// NewErrorResponseWithCode 创建带有错误代码的错误响应
// 返回包含错误代码和详细信息的ConversionResponse
func NewErrorResponseWithCode(message, code, detail string) *ConversionResponse {
return &ConversionResponse{
Success: false,
Error: message,
ErrorCode: code,
ErrorDetail: detail,
Timestamp: time.Now(),
Headers: make(map[string]string),
DebugInfo: make(map[string]interface{}),
}
}
// SetContent 设置响应内容和相关元数据
func (r *ConversionResponse) SetContent(content, contentType, targetFormat string) {
r.Content = content
r.ContentType = contentType
r.TargetFormat = targetFormat
r.ContentLength = int64(len(content))
}
// SetSource 设置源信息
func (r *ConversionResponse) SetSource(sourceURL, configURL string) {
r.SourceURL = sourceURL
r.ConfigURL = configURL
}
// SetStats 设置统计信息
func (r *ConversionResponse) SetStats(nodeCount, filteredCount int, proxyTypes []string) {
r.NodeCount = nodeCount
r.FilteredCount = filteredCount
r.ProxyTypes = proxyTypes
}
// SetProcessingTime 设置处理时间
func (r *ConversionResponse) SetProcessingTime(startTime time.Time) {
r.ProcessingTime = time.Since(startTime).Milliseconds()
}
// AddHeader 添加响应头
func (r *ConversionResponse) AddHeader(key, value string) {
if r.Headers == nil {
r.Headers = make(map[string]string)
}
r.Headers[key] = value
}
// AddDebugInfo 添加调试信息
func (r *ConversionResponse) AddDebugInfo(key string, value interface{}) {
if r.DebugInfo == nil {
r.DebugInfo = make(map[string]interface{})
}
r.DebugInfo[key] = value
}
// SetRequestID 设置请求ID
func (r *ConversionResponse) SetRequestID(requestID string) {
r.RequestID = requestID
}
// GenerateETag 生成ETag
// 基于内容和时间戳生成ETag
func (r *ConversionResponse) GenerateETag() string {
if r.Content == "" {
return ""
}
// 简单的ETag生成算法实际可以使用更复杂的方法
return fmt.Sprintf("\"%d-%d\"", len(r.Content), r.Timestamp.Unix())
}
// Validate 验证响应的有效性
// 返回error如果响应无效nil表示响应有效
func (r *ConversionResponse) Validate() error {
// 基本验证
if r.Timestamp.IsZero() {
return fmt.Errorf("timestamp cannot be zero")
}
if r.Success {
// 成功响应的验证
if r.Content == "" {
return fmt.Errorf("content cannot be empty for successful response")
}
if r.ContentType == "" {
return fmt.Errorf("content type cannot be empty for successful response")
}
if r.TargetFormat == "" {
return fmt.Errorf("target format cannot be empty for successful response")
}
} else {
// 错误响应的验证
if r.Error == "" {
return fmt.Errorf("error message cannot be empty for failed response")
}
if r.ErrorCode == "" {
return fmt.Errorf("error code cannot be empty for failed response")
}
}
return nil
}
// ToJSON 将响应转换为JSON格式
// 返回JSON格式的响应字符串
func (r *ConversionResponse) ToJSON() (string, error) {
if err := r.Validate(); err != nil {
return "", fmt.Errorf("response validation failed: %v", err)
}
data, err := json.Marshal(r)
if err != nil {
return "", fmt.Errorf("failed to marshal response: %v", err)
}
return string(data), nil
}
// ToJSONBytes 将响应转换为JSON字节数组
// 返回JSON格式的响应字节数组
func (r *ConversionResponse) ToJSONBytes() ([]byte, error) {
if err := r.Validate(); err != nil {
return nil, fmt.Errorf("response validation failed: %v", err)
}
return json.Marshal(r)
}
// FromJSON 从JSON字符串解析响应
// 解析JSON字符串到ConversionResponse
func (r *ConversionResponse) FromJSON(jsonStr string) error {
return json.Unmarshal([]byte(jsonStr), r)
}
// FromJSONBytes 从JSON字节数组解析响应
// 解析JSON字节数组到ConversionResponse
func (r *ConversionResponse) FromJSONBytes(data []byte) error {
return json.Unmarshal(data, r)
}
// IsSuccess 检查是否成功
// 返回true如果转换成功
func (r *ConversionResponse) IsSuccess() bool {
return r.Success
}
// GetError 获取错误信息
// 返回错误消息和错误代码
func (r *ConversionResponse) GetError() (string, string) {
return r.Error, r.ErrorCode
}
// GetContentLength 获取内容长度
// 返回内容的字节长度
func (r *ConversionResponse) GetContentLength() int64 {
return r.ContentLength
}
// GetProcessingTime 获取处理时间
// 返回处理时间的毫秒数
func (r *ConversionResponse) GetProcessingTime() int64 {
return r.ProcessingTime
}
// GetNodeCount 获取节点数量
// 返回处理的节点数量
func (r *ConversionResponse) GetNodeCount() int {
return r.NodeCount
}
// GetFilteredCount 获取过滤后的节点数量
// 返回过滤后的节点数量
func (r *ConversionResponse) GetFilteredCount() int {
return r.FilteredCount
}
// GetProxyTypes 获取代理类型列表
// 返回包含的代理类型
func (r *ConversionResponse) GetProxyTypes() []string {
return r.ProxyTypes
}
// GetHeaders 获取响应头
// 返回自定义响应头映射
func (r *ConversionResponse) GetHeaders() map[string]string {
return r.Headers
}
// GetDebugInfo 获取调试信息
// 返回调试信息映射
func (r *ConversionResponse) GetDebugInfo() map[string]interface{} {
return r.DebugInfo
}
// GetTimestamp 获取时间戳
// 返回处理时间戳
func (r *ConversionResponse) GetTimestamp() time.Time {
return r.Timestamp
}
// GetTargetFormat 获取目标格式
// 返回转换的目标格式
func (r *ConversionResponse) GetTargetFormat() string {
return r.TargetFormat
}
// GetSourceURL 获取源URL
// 返回处理的源URL
func (r *ConversionResponse) GetSourceURL() string {
return r.SourceURL
}
// GetConfigURL 获取配置URL
// 返回使用的配置URL
func (r *ConversionResponse) GetConfigURL() string {
return r.ConfigURL
}
// Clone 创建响应的副本
// 返回新的ConversionResponse实例
func (r *ConversionResponse) Clone() *ConversionResponse {
clone := &ConversionResponse{
Success: r.Success,
Content: r.Content,
ContentType: r.ContentType,
Error: r.Error,
ErrorCode: r.ErrorCode,
ErrorDetail: r.ErrorDetail,
Timestamp: r.Timestamp,
ProcessingTime: r.ProcessingTime,
TargetFormat: r.TargetFormat,
SourceURL: r.SourceURL,
ConfigURL: r.ConfigURL,
NodeCount: r.NodeCount,
FilteredCount: r.FilteredCount,
ContentLength: r.ContentLength,
ETag: r.ETag,
CacheControl: r.CacheControl,
RequestID: r.RequestID,
ServerInfo: r.ServerInfo,
}
// 深拷贝切片
if r.ProxyTypes != nil {
clone.ProxyTypes = make([]string, len(r.ProxyTypes))
copy(clone.ProxyTypes, r.ProxyTypes)
}
// 深拷贝映射
if r.Headers != nil {
clone.Headers = make(map[string]string)
for k, v := range r.Headers {
clone.Headers[k] = v
}
}
if r.DebugInfo != nil {
clone.DebugInfo = make(map[string]interface{})
for k, v := range r.DebugInfo {
clone.DebugInfo[k] = v
}
}
return clone
}
// WithRequestID 创建带有请求ID的响应副本
// 返回新的ConversionResponse实例包含指定的请求ID
func (r *ConversionResponse) WithRequestID(requestID string) *ConversionResponse {
clone := r.Clone()
clone.RequestID = requestID
return clone
}
// WithHeaders 创建带有自定义响应头的响应副本
// 返回新的ConversionResponse实例包含指定的响应头
func (r *ConversionResponse) WithHeaders(headers map[string]string) *ConversionResponse {
clone := r.Clone()
if clone.Headers == nil {
clone.Headers = make(map[string]string)
}
for k, v := range headers {
clone.Headers[k] = v
}
return clone
}
// WithCacheControl 创建带有缓存控制的响应副本
// 返回新的ConversionResponse实例包含指定的缓存控制
func (r *ConversionResponse) WithCacheControl(cacheControl string) *ConversionResponse {
clone := r.Clone()
clone.CacheControl = cacheControl
return clone
}
// ToErrorResponse 转换为错误响应
// 将当前响应转换为错误响应
func (r *ConversionResponse) ToErrorResponse(message, code string) *ConversionResponse {
r.Success = false
r.Error = message
r.ErrorCode = code
r.Content = ""
r.ContentType = ""
r.ContentLength = 0
return r
}
// ToSuccessResponse 转换为成功响应
// 将当前响应转换为成功响应
func (r *ConversionResponse) ToSuccessResponse(content, contentType, targetFormat string) *ConversionResponse {
r.Success = true
r.Error = ""
r.ErrorCode = ""
r.ErrorDetail = ""
r.SetContent(content, contentType, targetFormat)
return r
}
// String 返回响应的字符串表示
// 实现Stringer接口
func (r *ConversionResponse) String() string {
if r.Success {
return fmt.Sprintf("Success: %s format, %d nodes, %dms",
r.TargetFormat, r.NodeCount, r.ProcessingTime)
}
return fmt.Sprintf("Error: %s (%s)", r.Error, r.ErrorCode)
}