package mcp
import (
"encoding/json"
"fmt"
"github.com/spf13/cast"
)
var (
_ ClientRequest = (*PingRequest )(nil )
_ ClientRequest = (*InitializeRequest )(nil )
_ ClientRequest = (*CompleteRequest )(nil )
_ ClientRequest = (*SetLevelRequest )(nil )
_ ClientRequest = (*GetPromptRequest )(nil )
_ ClientRequest = (*ListPromptsRequest )(nil )
_ ClientRequest = (*ListResourcesRequest )(nil )
_ ClientRequest = (*ReadResourceRequest )(nil )
_ ClientRequest = (*SubscribeRequest )(nil )
_ ClientRequest = (*UnsubscribeRequest )(nil )
_ ClientRequest = (*CallToolRequest )(nil )
_ ClientRequest = (*ListToolsRequest )(nil )
)
var (
_ ClientNotification = (*CancelledNotification )(nil )
_ ClientNotification = (*ProgressNotification )(nil )
_ ClientNotification = (*InitializedNotification )(nil )
_ ClientNotification = (*RootsListChangedNotification )(nil )
)
var (
_ ClientResult = (*EmptyResult )(nil )
_ ClientResult = (*CreateMessageResult )(nil )
_ ClientResult = (*ListRootsResult )(nil )
)
var (
_ ServerRequest = (*PingRequest )(nil )
_ ServerRequest = (*CreateMessageRequest )(nil )
_ ServerRequest = (*ListRootsRequest )(nil )
)
var (
_ ServerNotification = (*CancelledNotification )(nil )
_ ServerNotification = (*ProgressNotification )(nil )
_ ServerNotification = (*LoggingMessageNotification )(nil )
_ ServerNotification = (*ResourceUpdatedNotification )(nil )
_ ServerNotification = (*ResourceListChangedNotification )(nil )
_ ServerNotification = (*ToolListChangedNotification )(nil )
_ ServerNotification = (*PromptListChangedNotification )(nil )
)
var (
_ ServerResult = (*EmptyResult )(nil )
_ ServerResult = (*InitializeResult )(nil )
_ ServerResult = (*CompleteResult )(nil )
_ ServerResult = (*GetPromptResult )(nil )
_ ServerResult = (*ListPromptsResult )(nil )
_ ServerResult = (*ListResourcesResult )(nil )
_ ServerResult = (*ReadResourceResult )(nil )
_ ServerResult = (*CallToolResult )(nil )
_ ServerResult = (*ListToolsResult )(nil )
)
func asType[T any ](content any ) (*T , bool ) {
tc , ok := content .(T )
if !ok {
return nil , false
}
return &tc , true
}
func AsTextContent (content any ) (*TextContent , bool ) {
return asType [TextContent ](content )
}
func AsImageContent (content any ) (*ImageContent , bool ) {
return asType [ImageContent ](content )
}
func AsAudioContent (content any ) (*AudioContent , bool ) {
return asType [AudioContent ](content )
}
func AsEmbeddedResource (content any ) (*EmbeddedResource , bool ) {
return asType [EmbeddedResource ](content )
}
func AsTextResourceContents (content any ) (*TextResourceContents , bool ) {
return asType [TextResourceContents ](content )
}
func AsBlobResourceContents (content any ) (*BlobResourceContents , bool ) {
return asType [BlobResourceContents ](content )
}
func NewJSONRPCResponse (id RequestId , result Result ) JSONRPCResponse {
return JSONRPCResponse {
JSONRPC : JSONRPC_VERSION ,
ID : id ,
Result : result ,
}
}
func NewJSONRPCResultResponse (id RequestId , result any ) JSONRPCResponse {
return JSONRPCResponse {
JSONRPC : JSONRPC_VERSION ,
ID : id ,
Result : result ,
}
}
func NewJSONRPCErrorDetails (code int , message string , data any ) JSONRPCErrorDetails {
return JSONRPCErrorDetails {
Code : code ,
Message : message ,
Data : data ,
}
}
func NewJSONRPCError (
id RequestId ,
code int ,
message string ,
data any ,
) JSONRPCError {
return JSONRPCError {
JSONRPC : JSONRPC_VERSION ,
ID : id ,
Error : NewJSONRPCErrorDetails (code , message , data ),
}
}
func NewProgressNotification (
token ProgressToken ,
progress float64 ,
total *float64 ,
message *string ,
) ProgressNotification {
notification := ProgressNotification {
Notification : Notification {
Method : "notifications/progress" ,
},
Params : struct {
ProgressToken ProgressToken `json:"progressToken"`
Progress float64 `json:"progress"`
Total float64 `json:"total,omitempty"`
Message string `json:"message,omitempty"`
}{
ProgressToken : token ,
Progress : progress ,
},
}
if total != nil {
notification .Params .Total = *total
}
if message != nil {
notification .Params .Message = *message
}
return notification
}
func NewLoggingMessageNotification (
level LoggingLevel ,
logger string ,
data any ,
) LoggingMessageNotification {
return LoggingMessageNotification {
Notification : Notification {
Method : "notifications/message" ,
},
Params : struct {
Level LoggingLevel `json:"level"`
Logger string `json:"logger,omitempty"`
Data any `json:"data"`
}{
Level : level ,
Logger : logger ,
Data : data ,
},
}
}
func NewPromptMessage (role Role , content Content ) PromptMessage {
return PromptMessage {
Role : role ,
Content : content ,
}
}
func NewTextContent (text string ) TextContent {
return TextContent {
Type : ContentTypeText ,
Text : text ,
}
}
func NewImageContent (data , mimeType string ) ImageContent {
return ImageContent {
Type : ContentTypeImage ,
Data : data ,
MIMEType : mimeType ,
}
}
func NewAudioContent (data , mimeType string ) AudioContent {
return AudioContent {
Type : ContentTypeAudio ,
Data : data ,
MIMEType : mimeType ,
}
}
func NewResourceLink (uri , name , description , mimeType string ) ResourceLink {
return ResourceLink {
Type : ContentTypeLink ,
URI : uri ,
Name : name ,
Description : description ,
MIMEType : mimeType ,
}
}
func NewEmbeddedResource (resource ResourceContents ) EmbeddedResource {
return EmbeddedResource {
Type : ContentTypeResource ,
Resource : resource ,
}
}
func NewToolResultText (text string ) *CallToolResult {
return &CallToolResult {
Content : []Content {
TextContent {
Type : ContentTypeText ,
Text : text ,
},
},
}
}
func NewToolResultJSON [T any ](data T ) (*CallToolResult , error ) {
b , err := json .Marshal (data )
if err != nil {
return nil , fmt .Errorf ("unable to marshal JSON: %w" , err )
}
return &CallToolResult {
Content : []Content {
TextContent {
Type : ContentTypeText ,
Text : string (b ),
},
},
StructuredContent : data ,
}, nil
}
func NewToolResultStructured (structured any , fallbackText string ) *CallToolResult {
return &CallToolResult {
Content : []Content {
TextContent {
Type : "text" ,
Text : fallbackText ,
},
},
StructuredContent : structured ,
}
}
func NewToolResultStructuredOnly (structured any ) *CallToolResult {
var fallbackText string
jsonBytes , err := json .Marshal (structured )
if err != nil {
fallbackText = fmt .Sprintf ("Error serializing structured content: %v" , err )
} else {
fallbackText = string (jsonBytes )
}
return &CallToolResult {
Content : []Content {
TextContent {
Type : "text" ,
Text : fallbackText ,
},
},
StructuredContent : structured ,
}
}
func NewToolResultImage (text , imageData , mimeType string ) *CallToolResult {
return &CallToolResult {
Content : []Content {
TextContent {
Type : ContentTypeText ,
Text : text ,
},
ImageContent {
Type : ContentTypeImage ,
Data : imageData ,
MIMEType : mimeType ,
},
},
}
}
func NewToolResultAudio (text , audioData , mimeType string ) *CallToolResult {
return &CallToolResult {
Content : []Content {
TextContent {
Type : ContentTypeText ,
Text : text ,
},
AudioContent {
Type : ContentTypeAudio ,
Data : audioData ,
MIMEType : mimeType ,
},
},
}
}
func NewToolResultResource (
text string ,
resource ResourceContents ,
) *CallToolResult {
return &CallToolResult {
Content : []Content {
TextContent {
Type : ContentTypeText ,
Text : text ,
},
EmbeddedResource {
Type : ContentTypeResource ,
Resource : resource ,
},
},
}
}
func NewToolResultError (text string ) *CallToolResult {
return &CallToolResult {
Content : []Content {
TextContent {
Type : ContentTypeText ,
Text : text ,
},
},
IsError : true ,
}
}
func NewToolResultErrorFromErr (text string , err error ) *CallToolResult {
if err != nil {
text = fmt .Sprintf ("%s: %v" , text , err )
}
return &CallToolResult {
Content : []Content {
TextContent {
Type : ContentTypeText ,
Text : text ,
},
},
IsError : true ,
}
}
func NewToolResultErrorf (format string , a ...any ) *CallToolResult {
return &CallToolResult {
Content : []Content {
TextContent {
Type : ContentTypeText ,
Text : fmt .Sprintf (format , a ...),
},
},
IsError : true ,
}
}
func NewListResourcesResult (
resources []Resource ,
nextCursor Cursor ,
) *ListResourcesResult {
return &ListResourcesResult {
PaginatedResult : PaginatedResult {
NextCursor : nextCursor ,
},
Resources : resources ,
}
}
func NewListResourceTemplatesResult (
templates []ResourceTemplate ,
nextCursor Cursor ,
) *ListResourceTemplatesResult {
return &ListResourceTemplatesResult {
PaginatedResult : PaginatedResult {
NextCursor : nextCursor ,
},
ResourceTemplates : templates ,
}
}
func NewReadResourceResult (text string ) *ReadResourceResult {
return &ReadResourceResult {
Contents : []ResourceContents {
TextResourceContents {
Text : text ,
},
},
}
}
func NewListPromptsResult (
prompts []Prompt ,
nextCursor Cursor ,
) *ListPromptsResult {
return &ListPromptsResult {
PaginatedResult : PaginatedResult {
NextCursor : nextCursor ,
},
Prompts : prompts ,
}
}
func NewGetPromptResult (
description string ,
messages []PromptMessage ,
) *GetPromptResult {
return &GetPromptResult {
Description : description ,
Messages : messages ,
}
}
func NewListToolsResult (tools []Tool , nextCursor Cursor ) *ListToolsResult {
return &ListToolsResult {
PaginatedResult : PaginatedResult {
NextCursor : nextCursor ,
},
Tools : tools ,
}
}
func NewInitializeResult (
protocolVersion string ,
capabilities ServerCapabilities ,
serverInfo Implementation ,
instructions string ,
) *InitializeResult {
return &InitializeResult {
ProtocolVersion : protocolVersion ,
Capabilities : capabilities ,
ServerInfo : serverInfo ,
Instructions : instructions ,
}
}
func FormatNumberResult (value float64 ) *CallToolResult {
return NewToolResultText (fmt .Sprintf ("%.2f" , value ))
}
func ExtractString (data map [string ]any , key string ) string {
if value , ok := data [key ]; ok {
if str , ok := value .(string ); ok {
return str
}
}
return ""
}
func ParseAnnotations (data map [string ]any ) *Annotations {
if data == nil {
return nil
}
annotations := &Annotations {}
if value , ok := data ["priority" ]; ok {
if value != nil {
if priority , err := cast .ToFloat64E (value ); err == nil {
annotations .Priority = &priority
}
}
}
if value , ok := data ["audience" ]; ok {
for _ , a := range cast .ToStringSlice (value ) {
a := Role (a )
if a == RoleUser || a == RoleAssistant {
annotations .Audience = append (annotations .Audience , a )
}
}
}
if value , ok := data ["lastModified" ]; ok {
if str , ok := value .(string ); ok {
annotations .LastModified = str
}
}
return annotations
}
func ExtractMap (data map [string ]any , key string ) map [string ]any {
if value , ok := data [key ]; ok {
if m , ok := value .(map [string ]any ); ok {
return m
}
}
return nil
}
func ParseContent (contentMap map [string ]any ) (Content , error ) {
contentType := ExtractString (contentMap , "type" )
var annotations *Annotations
if annotationsMap := ExtractMap (contentMap , "annotations" ); annotationsMap != nil {
annotations = ParseAnnotations (annotationsMap )
}
var meta *Meta
if metaMap := ExtractMap (contentMap , "_meta" ); metaMap != nil {
meta = NewMetaFromMap (metaMap )
}
switch contentType {
case ContentTypeText :
text := ExtractString (contentMap , "text" )
c := NewTextContent (text )
c .Annotations = annotations
c .Meta = meta
return c , nil
case ContentTypeImage :
data := ExtractString (contentMap , "data" )
mimeType := ExtractString (contentMap , "mimeType" )
if data == "" || mimeType == "" {
return nil , fmt .Errorf ("image data or mimeType is missing" )
}
c := NewImageContent (data , mimeType )
c .Annotations = annotations
c .Meta = meta
return c , nil
case ContentTypeAudio :
data := ExtractString (contentMap , "data" )
mimeType := ExtractString (contentMap , "mimeType" )
if data == "" || mimeType == "" {
return nil , fmt .Errorf ("audio data or mimeType is missing" )
}
c := NewAudioContent (data , mimeType )
c .Annotations = annotations
c .Meta = meta
return c , nil
case ContentTypeLink :
uri := ExtractString (contentMap , "uri" )
name := ExtractString (contentMap , "name" )
description := ExtractString (contentMap , "description" )
mimeType := ExtractString (contentMap , "mimeType" )
if uri == "" || name == "" {
return nil , fmt .Errorf ("resource_link uri or name is missing" )
}
c := NewResourceLink (uri , name , description , mimeType )
c .Annotations = annotations
return c , nil
case ContentTypeResource :
resourceMap := ExtractMap (contentMap , "resource" )
if resourceMap == nil {
return nil , fmt .Errorf ("resource is missing" )
}
resourceContents , err := ParseResourceContents (resourceMap )
if err != nil {
return nil , err
}
c := NewEmbeddedResource (resourceContents )
c .Annotations = annotations
c .Meta = meta
return c , nil
}
return nil , fmt .Errorf ("unsupported content type: %s" , contentType )
}
func ParseGetPromptResult (rawMessage *json .RawMessage ) (*GetPromptResult , error ) {
if rawMessage == nil {
return nil , fmt .Errorf ("response is nil" )
}
var jsonContent map [string ]any
if err := json .Unmarshal (*rawMessage , &jsonContent ); err != nil {
return nil , fmt .Errorf ("failed to unmarshal response: %w" , err )
}
result := GetPromptResult {}
meta , ok := jsonContent ["_meta" ]
if ok {
if metaMap , ok := meta .(map [string ]any ); ok {
result .Meta = NewMetaFromMap (metaMap )
}
}
description , ok := jsonContent ["description" ]
if ok {
if descriptionStr , ok := description .(string ); ok {
result .Description = descriptionStr
}
}
messages , ok := jsonContent ["messages" ]
if ok {
messagesArr , ok := messages .([]any )
if !ok {
return nil , fmt .Errorf ("messages is not an array" )
}
for _ , message := range messagesArr {
messageMap , ok := message .(map [string ]any )
if !ok {
return nil , fmt .Errorf ("message is not an object" )
}
roleStr := ExtractString (messageMap , "role" )
if roleStr == "" || (roleStr != string (RoleAssistant ) && roleStr != string (RoleUser )) {
return nil , fmt .Errorf ("unsupported role: %s" , roleStr )
}
contentMap , ok := messageMap ["content" ].(map [string ]any )
if !ok {
return nil , fmt .Errorf ("content is not an object" )
}
content , err := ParseContent (contentMap )
if err != nil {
return nil , err
}
result .Messages = append (result .Messages , NewPromptMessage (Role (roleStr ), content ))
}
}
return &result , nil
}
func ParseCallToolResult (rawMessage *json .RawMessage ) (*CallToolResult , error ) {
if rawMessage == nil {
return nil , fmt .Errorf ("response is nil" )
}
var jsonContent map [string ]any
if err := json .Unmarshal (*rawMessage , &jsonContent ); err != nil {
return nil , fmt .Errorf ("failed to unmarshal response: %w" , err )
}
var result CallToolResult
meta , ok := jsonContent ["_meta" ]
if ok {
if metaMap , ok := meta .(map [string ]any ); ok {
result .Meta = NewMetaFromMap (metaMap )
}
}
isError , ok := jsonContent ["isError" ]
if ok {
if isErrorBool , ok := isError .(bool ); ok {
result .IsError = isErrorBool
}
}
contents , ok := jsonContent ["content" ]
if !ok {
return nil , fmt .Errorf ("content is missing" )
}
contentArr , ok := contents .([]any )
if !ok {
return nil , fmt .Errorf ("content is not an array" )
}
for _ , content := range contentArr {
contentMap , ok := content .(map [string ]any )
if !ok {
return nil , fmt .Errorf ("content is not an object" )
}
content , err := ParseContent (contentMap )
if err != nil {
return nil , err
}
result .Content = append (result .Content , content )
}
structuredContent , ok := jsonContent ["structuredContent" ]
if ok {
result .StructuredContent = structuredContent
}
return &result , nil
}
func ParseResourceContents (contentMap map [string ]any ) (ResourceContents , error ) {
uri := ExtractString (contentMap , "uri" )
if uri == "" {
return nil , fmt .Errorf ("resource uri is missing" )
}
mimeType := ExtractString (contentMap , "mimeType" )
meta := ExtractMap (contentMap , "_meta" )
if _ , present := contentMap ["_meta" ]; present && meta == nil {
return nil , fmt .Errorf ("_meta must be an object" )
}
if text := ExtractString (contentMap , "text" ); text != "" {
return TextResourceContents {
Meta : meta ,
URI : uri ,
MIMEType : mimeType ,
Text : text ,
}, nil
}
if blob := ExtractString (contentMap , "blob" ); blob != "" {
return BlobResourceContents {
Meta : meta ,
URI : uri ,
MIMEType : mimeType ,
Blob : blob ,
}, nil
}
return nil , fmt .Errorf ("unsupported resource type" )
}
func ParseReadResourceResult (rawMessage *json .RawMessage ) (*ReadResourceResult , error ) {
if rawMessage == nil {
return nil , fmt .Errorf ("response is nil" )
}
var jsonContent map [string ]any
if err := json .Unmarshal (*rawMessage , &jsonContent ); err != nil {
return nil , fmt .Errorf ("failed to unmarshal response: %w" , err )
}
var result ReadResourceResult
meta , ok := jsonContent ["_meta" ]
if ok {
if metaMap , ok := meta .(map [string ]any ); ok {
result .Meta = NewMetaFromMap (metaMap )
}
}
contents , ok := jsonContent ["contents" ]
if !ok {
return nil , fmt .Errorf ("contents is missing" )
}
contentArr , ok := contents .([]any )
if !ok {
return nil , fmt .Errorf ("contents is not an array" )
}
for _ , content := range contentArr {
contentMap , ok := content .(map [string ]any )
if !ok {
return nil , fmt .Errorf ("content is not an object" )
}
content , err := ParseResourceContents (contentMap )
if err != nil {
return nil , err
}
result .Contents = append (result .Contents , content )
}
return &result , nil
}
func ParseArgument (request CallToolRequest , key string , defaultVal any ) any {
args := request .GetArguments ()
if _ , ok := args [key ]; !ok {
return defaultVal
} else {
return args [key ]
}
}
func ParseBoolean (request CallToolRequest , key string , defaultValue bool ) bool {
v := ParseArgument (request , key , defaultValue )
return cast .ToBool (v )
}
func ParseInt64 (request CallToolRequest , key string , defaultValue int64 ) int64 {
v := ParseArgument (request , key , defaultValue )
return cast .ToInt64 (v )
}
func ParseInt32 (request CallToolRequest , key string , defaultValue int32 ) int32 {
v := ParseArgument (request , key , defaultValue )
return cast .ToInt32 (v )
}
func ParseInt16 (request CallToolRequest , key string , defaultValue int16 ) int16 {
v := ParseArgument (request , key , defaultValue )
return cast .ToInt16 (v )
}
func ParseInt8 (request CallToolRequest , key string , defaultValue int8 ) int8 {
v := ParseArgument (request , key , defaultValue )
return cast .ToInt8 (v )
}
func ParseInt (request CallToolRequest , key string , defaultValue int ) int {
v := ParseArgument (request , key , defaultValue )
return cast .ToInt (v )
}
func ParseUInt (request CallToolRequest , key string , defaultValue uint ) uint {
v := ParseArgument (request , key , defaultValue )
return cast .ToUint (v )
}
func ParseUInt64 (request CallToolRequest , key string , defaultValue uint64 ) uint64 {
v := ParseArgument (request , key , defaultValue )
return cast .ToUint64 (v )
}
func ParseUInt32 (request CallToolRequest , key string , defaultValue uint32 ) uint32 {
v := ParseArgument (request , key , defaultValue )
return cast .ToUint32 (v )
}
func ParseUInt16 (request CallToolRequest , key string , defaultValue uint16 ) uint16 {
v := ParseArgument (request , key , defaultValue )
return cast .ToUint16 (v )
}
func ParseUInt8 (request CallToolRequest , key string , defaultValue uint8 ) uint8 {
v := ParseArgument (request , key , defaultValue )
return cast .ToUint8 (v )
}
func ParseFloat32 (request CallToolRequest , key string , defaultValue float32 ) float32 {
v := ParseArgument (request , key , defaultValue )
return cast .ToFloat32 (v )
}
func ParseFloat64 (request CallToolRequest , key string , defaultValue float64 ) float64 {
v := ParseArgument (request , key , defaultValue )
return cast .ToFloat64 (v )
}
func ParseString (request CallToolRequest , key string , defaultValue string ) string {
v := ParseArgument (request , key , defaultValue )
return cast .ToString (v )
}
func ParseStringMap (request CallToolRequest , key string , defaultValue map [string ]any ) map [string ]any {
v := ParseArgument (request , key , defaultValue )
return cast .ToStringMap (v )
}
func ToBoolPtr (b bool ) *bool {
return &b
}
func ToInt64Ptr (i int64 ) *int64 {
return &i
}
func GetTextFromContent (content any ) string {
switch c := content .(type ) {
case TextContent :
return c .Text
case map [string ]any :
if contentType , exists := c ["type" ]; exists && contentType == "text" {
if text , exists := c ["text" ].(string ); exists {
return text
}
}
return fmt .Sprintf ("%v" , content )
case string :
return c
default :
return fmt .Sprintf ("%v" , content )
}
}
func jsonToTask(jsonContent map [string ]any , result *GetTaskResult ) {
taskId , ok := jsonContent ["taskId" ]
if ok {
if taskIdStr , ok := taskId .(string ); ok {
result .TaskId = taskIdStr
}
}
taskStatus , ok := jsonContent ["status" ]
if ok {
if taskStatusStr , ok := taskStatus .(string ); ok {
result .Status = TaskStatus (taskStatusStr )
}
}
taskStatusMessage , ok := jsonContent ["statusMessage" ]
if ok {
if taskStatusMessageStr , ok := taskStatusMessage .(string ); ok {
result .StatusMessage = taskStatusMessageStr
}
}
createdAt , ok := jsonContent ["createdAt" ]
if ok {
if createdAtStr , ok := createdAt .(string ); ok {
result .CreatedAt = createdAtStr
}
}
lastUpdatedAt , ok := jsonContent ["lastUpdatedAt" ]
if ok {
if lastUpdatedAtStr , ok := lastUpdatedAt .(string ); ok {
result .LastUpdatedAt = lastUpdatedAtStr
}
}
ttl , ok := jsonContent ["ttl" ]
if ok {
if ttlFloat , ok := ttl .(float64 ); ok {
ttlInt64 := int64 (ttlFloat )
result .TTL = &ttlInt64
}
}
pollInterval , ok := jsonContent ["pollInterval" ]
if ok {
if pollIntervalFloat64 , ok := pollInterval .(float64 ); ok {
pollIntervalInt := int64 (pollIntervalFloat64 )
result .PollInterval = &pollIntervalInt
}
}
}
func ParseCancelTaskResult (rawMessage *json .RawMessage ) (*CancelTaskResult , error ) {
if rawMessage == nil {
return nil , fmt .Errorf ("response is nil" )
}
var jsonContent map [string ]any
if err := json .Unmarshal (*rawMessage , &jsonContent ); err != nil {
return nil , fmt .Errorf ("failed to unmarshal response: %w" , err )
}
convertResult := GetTaskResult {}
jsonToTask (jsonContent , &convertResult )
cancelResult := CancelTaskResult (convertResult )
meta , ok := jsonContent ["_meta" ]
if ok {
if metaMap , ok := meta .(map [string ]any ); ok {
cancelResult .Meta = NewMetaFromMap (metaMap )
}
}
return &cancelResult , nil
}
func ParseListTasksResult (rawMessage *json .RawMessage ) (*ListTasksResult , error ) {
if rawMessage == nil {
return nil , fmt .Errorf ("response is nil" )
}
var jsonContent map [string ]any
if err := json .Unmarshal (*rawMessage , &jsonContent ); err != nil {
return nil , fmt .Errorf ("failed to unmarshal response: %w" , err )
}
listTasksResult := ListTasksResult {}
meta , ok := jsonContent ["_meta" ]
if ok {
if metaMap , ok := meta .(map [string ]any ); ok {
listTasksResult .Meta = NewMetaFromMap (metaMap )
}
}
tasks , ok := jsonContent ["tasks" ]
if ok {
if taskArr , ok := tasks .([]any ); ok {
for _ , task := range taskArr {
if taskJsonContent , ok := task .(map [string ]any ); ok {
getTaskResult := GetTaskResult {}
jsonToTask (taskJsonContent , &getTaskResult )
listTasksResult .Tasks = append (listTasksResult .Tasks , getTaskResult .Task )
}
}
}
}
nextCursor , ok := jsonContent ["nextCursor" ]
if ok {
if cursorStr , ok := nextCursor .(string ); ok {
listTasksResult .NextCursor = Cursor (cursorStr )
}
}
return &listTasksResult , nil
}
func ParseTaskResultResult (rawMessage *json .RawMessage ) (*TaskResultResult , error ) {
if rawMessage == nil {
return nil , fmt .Errorf ("response is nil" )
}
var jsonContent map [string ]any
if err := json .Unmarshal (*rawMessage , &jsonContent ); err != nil {
return nil , fmt .Errorf ("failed to unmarshal response: %w" , err )
}
resultResult := TaskResultResult {}
meta , ok := jsonContent ["_meta" ]
if ok {
if metaMap , ok := meta .(map [string ]any ); ok {
resultResult .Meta = NewMetaFromMap (metaMap )
}
}
result , ok := jsonContent ["result" ]
if ok {
if resultMap , ok := result .(map [string ]any ); ok {
if isError , ok := resultMap ["isError" ].(bool ); ok {
resultResult .IsError = isError
}
if contents , ok := resultMap ["content" ].([]any ); ok {
for _ , content := range contents {
if contentMap , ok := content .(map [string ]any ); ok {
parsedContent , err := ParseContent (contentMap )
if err != nil {
return nil , err
}
resultResult .Content = append (resultResult .Content , parsedContent )
}
}
}
}
}
return &resultResult , nil
}
func ParseGetTaskResult (rawMessage *json .RawMessage ) (*GetTaskResult , error ) {
if rawMessage == nil {
return nil , fmt .Errorf ("response is nil" )
}
var jsonContent map [string ]any
if err := json .Unmarshal (*rawMessage , &jsonContent ); err != nil {
return nil , fmt .Errorf ("failed to unmarshal response: %w" , err )
}
result := GetTaskResult {}
meta , ok := jsonContent ["_meta" ]
if ok {
if metaMap , ok := meta .(map [string ]any ); ok {
result .Meta = NewMetaFromMap (metaMap )
}
}
jsonToTask (jsonContent , &result )
return &result , nil
}
The pages are generated with Golds v0.8.4 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .