diff options
| author | Charlie Stanton <charlie@shtanton.xyz> | 2024-04-07 16:04:23 +0100 | 
|---|---|---|
| committer | Charlie Stanton <charlie@shtanton.xyz> | 2024-04-07 16:04:23 +0100 | 
| commit | 7162ae8c641314846f0b565d7614ac8d71dbd628 (patch) | |
| tree | fba1b545e6d20dac7f958bedf83afc61fcbbc256 /walk | |
| parent | 658900fcae610caace83a112ac0ee865108ebc92 (diff) | |
| download | stred-go-7162ae8c641314846f0b565d7614ac8d71dbd628.tar | |
Add merge command
Diffstat (limited to 'walk')
| -rw-r--r-- | walk/walk.go | 85 | 
1 files changed, 85 insertions, 0 deletions
| diff --git a/walk/walk.go b/walk/walk.go index 3fba62f..e66feff 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -148,3 +148,88 @@ func (item WalkItem) Debug() string {  	builder.WriteString(item.Value.Debug())  	return builder.String()  } + +func Merge(first Value, second Value) []Value { +	switch first := first.(type) { +	case NullValue: +		return []Value {first, second} +	case BoolValue: +		return []Value {first, second} +	case NumberValue: +		return []Value {first, second} +	case StringValue: +		return []Value {first, second} +	case ArrayValue: +		secondArr, isArr := second.(ArrayValue) +		if !isArr { +			return []Value {first, second} +		} + +		if len(first) == 0 { +			return []Value {second} +		} + +		if len(secondArr) == 0 { +			return []Value {first} +		} + +		var res ArrayValue +		for _, el := range first[:len(first) - 1] { +			res = append(res, el) +		} +		midFirst := first[len(first) - 1] +		midSecond := secondArr[0] +		if midFirst.Index == midSecond.Index { +			for _, el := range Merge(midFirst.Value, midSecond.Value) { +				res = append(res, ArrayElement { +					Index: midFirst.Index, +					Value: el, +				}) +			} +		} else { +			res = append(res, midFirst, midSecond) +		} +		for _, el := range secondArr[1:] { +			res = append(res, el) +		} + +		return []Value {res} +	case MapValue: +		secondMap, isMap := second.(MapValue) +		if !isMap { +			return []Value {first, second} +		} + +		if len(first) == 0 { +			return []Value {second} +		} + +		if len(secondMap) == 0 { +			return []Value {first} +		} + +		var res MapValue +		for _, el := range first[:len(first) - 1] { +			res = append(res, el) +		} +		midFirst := first[len(first) - 1] +		midSecond := secondMap[0] +		if midFirst.Key == midSecond.Key { +			for _, el := range Merge(midFirst.Value, midSecond.Value) { +				res = append(res, MapElement { +					Key: midFirst.Key, +					Value: el, +				}) +			} +		} else { +			res = append(res, midFirst, midSecond) +		} +		for _, el := range secondMap[1:] { +			res = append(res, el) +		} + +		return []Value {res} +	default: +		panic("first is invalid value type") +	} +} | 
