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