trpc.group/trpc-go/trpc-cmdline@v1.0.9/util/apidocs/method.go (about) 1 // Tencent is pleased to support the open source community by making tRPC available. 2 // 3 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 4 // All rights reserved. 5 // 6 // If you have downloaded a copy of the tRPC source code from Tencent, 7 // please note that tRPC source code is licensed under the Apache 2.0 License, 8 // A copy of the Apache 2.0 License is included in this file. 9 10 package apidocs 11 12 import "sort" 13 14 // MethodStruct defines the detailed information of a method in apidocs. 15 type MethodStruct struct { 16 Summary string `json:"summary"` // Comments of method. 17 OperationID string `json:"operationId"` // Name of method. 18 Responses map[string]MediaStruct `json:"responses"` // Response. 19 Parameters []*ParametersStruct `json:"parameters"` // Parameters. 20 Tags []string `json:"tags"` // The service to which the method belongs. 21 Description string `json:"description,omitempty"` // Description of the method. 22 } 23 24 // Methods is the set of methods. 25 type Methods struct { 26 Elements map[string]*MethodStruct 27 Rank map[string]int 28 } 29 30 // Put inserts an element into the ordered map, and records the element's rank in "Rank". 31 func (methods *Methods) Put(key string, value *MethodStruct) { 32 methods.Elements[key] = value 33 34 if methods.Rank != nil { 35 if _, ok := methods.Rank[key]; !ok { 36 methods.Rank[key] = len(methods.Elements) 37 } 38 } 39 } 40 41 // UnmarshalJSON deserializes JSON data. 42 func (methods *Methods) UnmarshalJSON(b []byte) error { 43 return OrderedUnmarshalJSON(b, &methods.Elements, &methods.Rank) 44 } 45 46 // MarshalJSON serializes the method to JSON. 47 func (methods Methods) MarshalJSON() ([]byte, error) { 48 return OrderedMarshalJSON(methods.Elements, methods.Rank) 49 } 50 51 func (methods *Methods) orderedEach(f func(k string, m *MethodStruct)) { 52 if methods == nil { 53 return 54 } 55 56 var keys []string 57 for k := range methods.Elements { 58 keys = append(keys, k) 59 } 60 61 if methods.Rank != nil { 62 sort.Slice(keys, func(i, j int) bool { 63 return methods.Rank[keys[i]] < methods.Rank[keys[j]] 64 }) 65 } else { 66 sort.Strings(keys) 67 } 68 69 for _, k := range keys { 70 f(k, methods.Elements[k]) 71 } 72 } 73 74 func (m MethodStruct) refs() []string { 75 var refs []string 76 for _, responses := range m.Responses { 77 if len(responses.Schema.Ref) > 0 { 78 refs = append(refs, GetNameByRef(responses.Schema.Ref)) 79 } 80 } 81 for _, parameter := range m.Parameters { 82 if parameter.Schema != nil && len(parameter.Schema.Ref) > 0 { 83 refs = append(refs, GetNameByRef(parameter.Schema.Ref)) 84 } 85 if parameter.Items != nil { 86 refs = append(refs, parameter.Items.refs(make(map[string]bool))...) 87 } 88 } 89 return refs 90 } 91 92 // GetMethodX converts MethodStruct to OpenAPI v3 interface. 93 func (m MethodStruct) GetMethodX() *MethodStructX { 94 methodX := &MethodStructX{ 95 Summary: m.Summary, 96 OperationID: m.OperationID, 97 Responses: make(map[string]BodyContentStruct), 98 RequestBody: nil, 99 Tags: m.Tags, 100 Description: m.Description, 101 } 102 103 // Returned values. 104 for status, r := range m.Responses { 105 resp := BodyContentStruct{ 106 Description: r.Description, 107 Content: map[string]MediaStruct{ 108 "application/json": { 109 Schema: r.Schema, 110 }, 111 }, 112 } 113 methodX.Responses[status] = resp 114 } 115 116 // Parameters. 117 var props []*PropertyStruct 118 for _, param := range m.Parameters { 119 if param.In != "body" { 120 methodX.Parameters = append(methodX.Parameters, param.GetParametersStructX()) 121 continue 122 } 123 124 if param.Schema != nil && param.Schema.Ref != "" { 125 methodX.RequestBody = param.GetRequestBody() 126 continue 127 } 128 129 props = append(props, param.GetProperty()) 130 } 131 132 if len(props) != 0 { 133 methodX.RequestBody = &BodyContentStruct{ 134 Content: map[string]MediaStruct{ 135 "application/json": { 136 Schema: SchemaStruct{ 137 Properties: props, 138 }, 139 }, 140 }, 141 } 142 } 143 144 return methodX 145 } 146 147 // GetMethodsX converts MethodStruct to OpenAPI v3 interface. 148 func (methods Methods) GetMethodsX() MethodsX { 149 methodsX := MethodsX{Elements: make(map[string]*MethodStructX)} 150 methodsX.Rank = methods.Rank 151 methods.orderedEach(func(name string, method *MethodStruct) { 152 methodsX.Elements[name] = method.GetMethodX() 153 }) 154 return methodsX 155 }