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