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 := &registry.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 := &registry.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  }