rewrite into get and set functions
This commit is contained in:
		
							parent
							
								
									20a0b66e5b
								
							
						
					
					
						commit
						5b3d257df4
					
				|  | @ -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 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue