github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/internal/util.go (about)

     1  package internal
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  )
     7  
     8  // RemainingKeys will inspect a struct and compare it to a map. Any struct
     9  // field that does not have a JSON tag that matches a key in the map or
    10  // a matching lower-case field in the map will be returned as an extra.
    11  //
    12  // This is useful for determining the extra fields returned in response bodies
    13  // for resources that can contain an arbitrary or dynamic number of fields.
    14  func RemainingKeys(s interface{}, m map[string]interface{}) (extras map[string]interface{}) {
    15  	extras = make(map[string]interface{})
    16  	for k, v := range m {
    17  		extras[k] = v
    18  	}
    19  
    20  	valueOf := reflect.ValueOf(s)
    21  	typeOf := reflect.TypeOf(s)
    22  	for i := 0; i < valueOf.NumField(); i++ {
    23  		field := typeOf.Field(i)
    24  
    25  		lowerField := strings.ToLower(field.Name)
    26  		delete(extras, lowerField)
    27  
    28  		if tagValue := field.Tag.Get("json"); tagValue != "" && tagValue != "-" {
    29  			delete(extras, tagValue)
    30  		}
    31  	}
    32  
    33  	return
    34  }