// Author: NiuJiuRu // Email: niujiuru@qq.com package jsonrpc2 import ( "encoding/json" "fmt" ) type ErrorCode int const ( ErrParse ErrorCode = -32700 // 解析错误: "Parse error" ErrInvalidRequest ErrorCode = -32600 // 无效请求: "Invalid request" ErrMethodNotFound ErrorCode = -32601 // 无效方法: "Method not found" ErrInvalidParams ErrorCode = -32602 // 无效参数: "Invalid params" ErrInternal ErrorCode = -32603 // 内部错误: "Internal error" ) type Request struct { JSONRPC string `json:"jsonrpc"` // 版本号, 固定: "2.0" Method string `json:"method"` // 调用方法, 执行函数名 Params json.RawMessage `json:"params,omitempty"` // 请求参数, 可选可为空 ID int `json:"id"` // 请求ID, 用于标识请求 } type Error struct { Code ErrorCode `json:"code"` // 错误码 Message string `json:"message"` // 错误信息 } func (e Error) Error() string { return e.Message } type Response struct { JSONRPC string `json:"jsonrpc"` // 版本号, 固定: "2.0" Result json.RawMessage `json:"result,omitempty"` // 响应结果, 可选可为空 Error *Error `json:"error,omitempty"` // 错误信息, 可选可为空 ID int `json:"id"` // 应答ID, 响应匹配请求 } // 解析请求数据 func ParseRequest(jsonStr string) (*Request, error) { var req Request if err := json.Unmarshal([]byte(jsonStr), &req); err != nil { return nil, err } return &req, nil } // 构建响应数据 func BuildResult(id int, result any) (*Response, error) { b, err := json.Marshal(result) if err != nil { return nil, err } return &Response{ JSONRPC: "2.0", Result: b, ID: id, }, nil } // 构建错误响应 func BuildError(id int, code ErrorCode, message string) *Response { return &Response{ JSONRPC: "2.0", Error: &Error{ Code: code, Message: message, }, ID: id, } } // 构建解析错误 func BuildParseError(id int) *Response { return BuildError(id, ErrParse, "Parse error") } // 构建无效请求 func BuildInvalidRequest(id int) *Response { return BuildError(id, ErrInvalidRequest, "Invalid request") } // 构建无效方法 func BuildMethodNotFound(id int) *Response { return BuildError(id, ErrMethodNotFound, "Method not found") } // 构建无效参数 func BuildInvalidParams(id int) *Response { return BuildError(id, ErrInvalidParams, "Invalid params") } // 构建内部错误 func BuildInternalError(id int) *Response { return BuildError(id, ErrInternal, "Internal error") } // 应答转字符串 func (resp *Response) String() (string, error) { b, err := json.Marshal(resp) if err != nil { return "", fmt.Errorf("marshal response: %w", err) } return string(b), nil }