github.com/MontFerret/ferret@v0.18.0/pkg/stdlib/objects/merge.go (about) 1 package objects 2 3 import ( 4 "context" 5 6 "github.com/MontFerret/ferret/pkg/runtime/core" 7 "github.com/MontFerret/ferret/pkg/runtime/values" 8 "github.com/MontFerret/ferret/pkg/runtime/values/types" 9 ) 10 11 // MERGE merge the given objects into a single object. 12 // @param {Object, repeated} objects - Objects to merge. 13 // @return {Object} - Object created by merging. 14 func Merge(_ context.Context, args ...core.Value) (core.Value, error) { 15 err := core.ValidateArgs(args, 1, core.MaxArgs) 16 17 if err != nil { 18 return values.None, err 19 } 20 21 objs := values.NewArrayWith(args...) 22 23 if len(args) == 1 && args[0].Type().Equals(types.Array) { 24 objs = args[0].(*values.Array) 25 } 26 27 err = validateArrayOf(types.Object, objs) 28 29 if err != nil { 30 return values.None, err 31 } 32 33 return mergeArray(objs), nil 34 } 35 36 func mergeArray(arr *values.Array) *values.Object { 37 merged, obj := values.NewObject(), values.NewObject() 38 39 arr.ForEach(func(arrValue core.Value, arrIdx int) bool { 40 obj = arrValue.(*values.Object) 41 obj.ForEach(func(objValue core.Value, objKey string) bool { 42 cloneable, ok := objValue.(core.Cloneable) 43 44 if ok { 45 objValue = cloneable.Clone() 46 } 47 48 merged.Set(values.NewString(objKey), objValue) 49 50 return true 51 }) 52 return true 53 }) 54 55 return merged 56 } 57 58 func validateArrayOf(typ core.Type, arr *values.Array) (err error) { 59 for idx := values.NewInt(0); idx < arr.Length(); idx++ { 60 if err != nil { 61 break 62 } 63 err = core.ValidateType(arr.Get(idx), typ) 64 } 65 return 66 }