1
0
Fork 0
secondly/field.go

83 lines
1.6 KiB
Go
Raw Normal View History

2015-08-29 12:41:20 +00:00
package secondly
2015-08-29 12:25:47 +00:00
import (
"log"
"reflect"
)
type field struct {
2015-08-29 14:35:51 +00:00
Path string `json:"path"`
Name string `json:"name"`
Kind string `json:"kind"`
2015-08-29 16:34:10 +00:00
Value interface{} `json:"value"`
2015-08-29 12:25:47 +00:00
}
2015-08-29 14:32:39 +00:00
func extractFields(st interface{}, path string) []field {
var res []field
2015-08-29 12:25:47 +00:00
val := reflect.ValueOf(st)
if val.Kind() == reflect.Ptr {
val = reflect.Indirect(val)
}
typ := val.Type()
2015-08-29 12:25:47 +00:00
for i := 0; i < val.NumField(); i++ {
ftyp := typ.Field(i)
fval := val.Field(i)
2015-08-29 16:34:10 +00:00
tag := ftyp.Tag.Get("json")
2015-08-29 12:25:47 +00:00
switch kind := fval.Kind(); kind {
case reflect.Struct:
2015-08-29 16:34:10 +00:00
sub := extractFields(fval.Interface(), path+tag+".")
2015-08-29 14:32:39 +00:00
res = append(res, sub...)
2015-08-29 12:25:47 +00:00
case reflect.Bool,
reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64,
reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Float32,
reflect.Float64,
reflect.String:
2015-08-29 14:32:39 +00:00
res = append(res, field{
2015-08-29 16:34:10 +00:00
Path: path + tag,
2015-08-29 14:35:51 +00:00
Name: ftyp.Name,
Kind: kind.String(),
Value: fval.Interface(),
2015-08-29 14:32:39 +00:00
})
2015-08-29 12:25:47 +00:00
default:
2015-08-29 16:34:10 +00:00
log.Printf("Field type %q not supported for field %q\n", kind, path+tag)
2015-08-29 12:25:47 +00:00
}
}
return res
}
2015-08-29 12:25:59 +00:00
func diff(a, b interface{}) map[string][]interface{} {
2015-08-29 14:32:39 +00:00
af := indexFields(extractFields(a, ""))
bf := indexFields(extractFields(b, ""))
2015-08-29 12:25:59 +00:00
res := make(map[string][]interface{})
for name, f := range af {
2015-08-29 14:35:51 +00:00
if bf[name].Value != f.Value {
res[name] = []interface{}{f.Value, bf[name].Value}
2015-08-29 12:25:59 +00:00
}
}
return res
}
2015-08-29 14:32:39 +00:00
func indexFields(fields []field) map[string]field {
res := make(map[string]field)
for _, f := range fields {
res[f.Path] = f
}
return res
}