Blame vendor/github.com/gophercloud/gophercloud/internal/util.go

Packit 63bb0d
package internal
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"reflect"
Packit 63bb0d
	"strings"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
// RemainingKeys will inspect a struct and compare it to a map. Any struct
Packit 63bb0d
// field that does not have a JSON tag that matches a key in the map or
Packit 63bb0d
// a matching lower-case field in the map will be returned as an extra.
Packit 63bb0d
//
Packit 63bb0d
// This is useful for determining the extra fields returned in response bodies
Packit 63bb0d
// for resources that can contain an arbitrary or dynamic number of fields.
Packit 63bb0d
func RemainingKeys(s interface{}, m map[string]interface{}) (extras map[string]interface{}) {
Packit 63bb0d
	extras = make(map[string]interface{})
Packit 63bb0d
	for k, v := range m {
Packit 63bb0d
		extras[k] = v
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	valueOf := reflect.ValueOf(s)
Packit 63bb0d
	typeOf := reflect.TypeOf(s)
Packit 63bb0d
	for i := 0; i < valueOf.NumField(); i++ {
Packit 63bb0d
		field := typeOf.Field(i)
Packit 63bb0d
Packit 63bb0d
		lowerField := strings.ToLower(field.Name)
Packit 63bb0d
		delete(extras, lowerField)
Packit 63bb0d
Packit 63bb0d
		if tagValue := field.Tag.Get("json"); tagValue != "" && tagValue != "-" {
Packit 63bb0d
			delete(extras, tagValue)
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return
Packit 63bb0d
}