first commit
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
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
This commit is contained in:
399
internal/conversion/response.go
Normal file
399
internal/conversion/response.go
Normal file
@@ -0,0 +1,399 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user