rewrite into get and set functions

This commit is contained in:
filifa 2024-07-12 21:23:21 -05:00
parent 20a0b66e5b
commit 5b3d257df4
1 changed files with 54 additions and 11 deletions

View File

@ -48,7 +48,7 @@ func expand(arr []any, idx int) []any {
return all
}
func setValue(obj any, key string, value any) error {
func setLeaf(obj any, key string, value any) error {
var err error
switch v := obj.(type) {
case map[string]any:
@ -72,40 +72,83 @@ func setValue(obj any, key string, value any) error {
return err
}
func patch(obj any, path string, value any) error {
func getLeaf(key string, obj any) (any, error) {
switch v := obj.(type) {
case map[string]any:
val, ok := v[key]
if !ok {
return nil, errors.New("invalid key")
}
return val, nil
case []any:
idx, err := strconv.Atoi(key)
if err != nil {
return nil, err
}
if idx < 0 || idx >= len(v) {
return nil, errors.New("invalid index")
}
return v[idx], nil
default:
return nil, errors.New("couldn't determine type")
}
}
func set(path string, obj any, value any) error {
elems := strings.Split(path, "/")
leaf := elems[len(elems)-1]
leafPath := strings.Join(elems[:len(elems)-1], "/")
parent, err := get(leafPath, obj)
if err != nil {
return err
}
err = setLeaf(parent, leaf, value)
return err
}
func get(path string, obj any) (any, error) {
var err error
first, rest, found := strings.Cut(path, "/")
log.Println(first, rest)
if !found {
err = setValue(obj, first, value)
return err
return getLeaf(first, obj)
} else if first == "" {
err = patch(obj, rest, value)
return err
return get(rest, obj)
}
switch v := obj.(type) {
case map[string]any:
err = patch(v[first], rest, value)
val, ok := v[first]
if !ok {
return v, errors.New("invalid key")
}
return get(rest, val)
case []any:
idx, err := strconv.Atoi(first)
if err != nil {
break
}
v = expand(v, idx)
err = patch(v[idx], rest, value)
if idx < 0 || idx >= len(v) {
return v, errors.New("invalid index")
}
return get(rest, v[idx])
default:
err = errors.New("couldn't determine type")
}
return err
return obj, err
}
func (f *FeedResponse) Patch(instr *instruction) error {
// TODO: need to handle each type of instruction separately: add,
// replace, remove, copy, move
log.Println("updating", instr.Path)
err := patch(map[string]any(*f), instr.Path, instr.Value)
err := set(instr.Path, map[string]any(*f), instr.Value)
return err
}