gitee.com/sasukebo/go-micro/v4@v4.7.1/server/extractor.go (about) 1 package server 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 8 "gitee.com/sasukebo/go-micro/v4/registry" 9 ) 10 11 func extractValue(v reflect.Type, d int) *registry.Value { 12 if d == 3 { 13 return nil 14 } 15 if v == nil { 16 return nil 17 } 18 19 if v.Kind() == reflect.Ptr { 20 v = v.Elem() 21 } 22 23 arg := ®istry.Value{ 24 Name: v.Name(), 25 Type: v.Name(), 26 } 27 28 switch v.Kind() { 29 case reflect.Struct: 30 for i := 0; i < v.NumField(); i++ { 31 f := v.Field(i) 32 if f.PkgPath != "" { 33 continue 34 } 35 val := extractValue(f.Type, d+1) 36 if val == nil { 37 continue 38 } 39 40 // if we can find a json tag use it 41 if tags := f.Tag.Get("json"); len(tags) > 0 { 42 parts := strings.Split(tags, ",") 43 if parts[0] == "-" || parts[0] == "omitempty" { 44 continue 45 } 46 val.Name = parts[0] 47 } 48 49 // if there's no name default it 50 if len(val.Name) == 0 { 51 val.Name = v.Field(i).Name 52 } 53 54 // still no name then continue 55 if len(val.Name) == 0 { 56 continue 57 } 58 59 arg.Values = append(arg.Values, val) 60 } 61 case reflect.Slice: 62 p := v.Elem() 63 if p.Kind() == reflect.Ptr { 64 p = p.Elem() 65 } 66 arg.Type = "[]" + p.Name() 67 } 68 69 return arg 70 } 71 72 func extractEndpoint(method reflect.Method) *registry.Endpoint { 73 if method.PkgPath != "" { 74 return nil 75 } 76 77 var rspType, reqType reflect.Type 78 var stream bool 79 mt := method.Type 80 81 switch mt.NumIn() { 82 case 3: 83 reqType = mt.In(1) 84 rspType = mt.In(2) 85 case 4: 86 reqType = mt.In(2) 87 rspType = mt.In(3) 88 default: 89 return nil 90 } 91 92 // are we dealing with a stream? 93 switch rspType.Kind() { 94 case reflect.Func, reflect.Interface: 95 stream = true 96 } 97 98 request := extractValue(reqType, 0) 99 response := extractValue(rspType, 0) 100 101 ep := ®istry.Endpoint{ 102 Name: method.Name, 103 Request: request, 104 Response: response, 105 Metadata: make(map[string]string), 106 } 107 108 // set endpoint metadata for stream 109 if stream { 110 ep.Metadata = map[string]string{ 111 "stream": fmt.Sprintf("%v", stream), 112 } 113 } 114 115 return ep 116 } 117 118 func extractSubValue(typ reflect.Type) *registry.Value { 119 var reqType reflect.Type 120 switch typ.NumIn() { 121 case 1: 122 reqType = typ.In(0) 123 case 2: 124 reqType = typ.In(1) 125 case 3: 126 reqType = typ.In(2) 127 default: 128 return nil 129 } 130 return extractValue(reqType, 0) 131 }