Commit 16e07c7d authored by ymqytw's avatar ymqytw

Support replaceKeys patch strategy and directive

parent 7bc6da0b
...@@ -23,9 +23,11 @@ import ( ...@@ -23,9 +23,11 @@ import (
) )
var ( var (
ErrBadJSONDoc = errors.New("Invalid JSON document") ErrBadJSONDoc = errors.New("invalid JSON document")
ErrNoListOfLists = errors.New("Lists of lists are not supported") ErrNoListOfLists = errors.New("lists of lists are not supported")
ErrBadPatchFormatForPrimitiveList = errors.New("Invalid patch format of primitive list") ErrBadPatchFormatForPrimitiveList = errors.New("invalid patch format of primitive list")
ErrBadPatchFormatForRetainKeys = errors.New("invalid patch format of retainKeys")
ErrPatchContentNotMatchRetainKeys = errors.New("patch content doesn't match retainKeys list")
) )
func ErrNoMergeKey(m map[string]interface{}, k string) error { func ErrNoMergeKey(m map[string]interface{}, k string) error {
......
...@@ -17,16 +17,25 @@ import ( ...@@ -17,16 +17,25 @@ import (
"unicode/utf8" "unicode/utf8"
) )
const (
patchStrategyTagKey = "patchStrategy"
patchMergeKeyTagKey = "patchMergeKey"
)
// Finds the patchStrategy and patchMergeKey struct tag fields on a given // Finds the patchStrategy and patchMergeKey struct tag fields on a given
// struct field given the struct type and the JSON name of the field. // struct field given the struct type and the JSON name of the field.
// It returns field type, a slice of patch strategies, merge key and error.
// TODO: fix the returned errors to be introspectable. // TODO: fix the returned errors to be introspectable.
func LookupPatchMetadata(t reflect.Type, jsonField string) (reflect.Type, string, string, error) { func LookupPatchMetadata(t reflect.Type, jsonField string) (
elemType reflect.Type, patchStrategies []string, patchMergeKey string, e error) {
if t.Kind() == reflect.Map { if t.Kind() == reflect.Map {
return t.Elem(), "", "", nil elemType = t.Elem()
return
} }
if t.Kind() != reflect.Struct { if t.Kind() != reflect.Struct {
return nil, "", "", fmt.Errorf("merging an object in json but data type is not map or struct, instead is: %s", e = fmt.Errorf("merging an object in json but data type is not map or struct, instead is: %s",
t.Kind().String()) t.Kind().String())
return
} }
jf := []byte(jsonField) jf := []byte(jsonField)
// Find the field that the JSON library would use. // Find the field that the JSON library would use.
...@@ -50,11 +59,14 @@ func LookupPatchMetadata(t reflect.Type, jsonField string) (reflect.Type, string ...@@ -50,11 +59,14 @@ func LookupPatchMetadata(t reflect.Type, jsonField string) (reflect.Type, string
for i := 1; i < len(f.index); i++ { for i := 1; i < len(f.index); i++ {
tjf = tjf.Type.Field(f.index[i]) tjf = tjf.Type.Field(f.index[i])
} }
patchStrategy := tjf.Tag.Get("patchStrategy") patchStrategy := tjf.Tag.Get(patchStrategyTagKey)
patchMergeKey := tjf.Tag.Get("patchMergeKey") patchMergeKey = tjf.Tag.Get(patchMergeKeyTagKey)
return tjf.Type, patchStrategy, patchMergeKey, nil patchStrategies = strings.Split(patchStrategy, ",")
elemType = tjf.Type
return
} }
return nil, "", "", fmt.Errorf("unable to find api field in struct %s for the json field %q", t.Name(), jsonField) e = fmt.Errorf("unable to find api field in struct %s for the json field %q", t.Name(), jsonField)
return
} }
// A field represents a single field found in a struct. // A field represents a single field found in a struct.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment