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