Add functionality to visit values in `dyn.Value` tree (#1142)
## Changes
This change adds the following functions:
* `dyn.Get(value, "foo.bar") -> (dyn.Value, error)`
* `dyn.Set(value, "foo.bar", newValue) -> (dyn.Value, error)`
* `dyn.Map(value, "foo.bar", func) -> (dyn.Value, error)`
And equivalent functions that take a previously constructed `dyn.Path`:
* `dyn.GetByPath(value, dyn.Path) -> (dyn.Value, error)`
* `dyn.SetByPath(value, dyn.Path, newValue) -> (dyn.Value, error)`
* `dyn.MapByPath(value, dyn.Path, func) -> (dyn.Value, error)`
Changes made by the "set" and "map" functions are never reflected in the
input argument; they return new `dyn.Value` instances for all nodes in
the path leading up to the changed value.
## Tests
New unit tests cover all critical paths.
2024-01-24 18:38:46 +00:00
|
|
|
package dyn
|
|
|
|
|
|
|
|
// Get returns the value inside the specified value at the specified path.
|
|
|
|
// It is identical to [GetByPath], except that it takes a string path instead of a [Path].
|
|
|
|
func Get(v Value, path string) (Value, error) {
|
|
|
|
p, err := NewPathFromString(path)
|
|
|
|
if err != nil {
|
|
|
|
return InvalidValue, err
|
|
|
|
}
|
|
|
|
return GetByPath(v, p)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetByPath returns the value inside the specified value at the specified path.
|
|
|
|
// If the path doesn't exist, it returns InvalidValue and an error.
|
|
|
|
func GetByPath(v Value, p Path) (Value, error) {
|
|
|
|
out := InvalidValue
|
2024-03-08 14:33:01 +00:00
|
|
|
_, err := visit(v, EmptyPath, NewPatternFromPath(p), visitOptions{
|
2024-03-07 13:56:50 +00:00
|
|
|
fn: func(_ Path, ev Value) (Value, error) {
|
Add functionality to visit values in `dyn.Value` tree (#1142)
## Changes
This change adds the following functions:
* `dyn.Get(value, "foo.bar") -> (dyn.Value, error)`
* `dyn.Set(value, "foo.bar", newValue) -> (dyn.Value, error)`
* `dyn.Map(value, "foo.bar", func) -> (dyn.Value, error)`
And equivalent functions that take a previously constructed `dyn.Path`:
* `dyn.GetByPath(value, dyn.Path) -> (dyn.Value, error)`
* `dyn.SetByPath(value, dyn.Path, newValue) -> (dyn.Value, error)`
* `dyn.MapByPath(value, dyn.Path, func) -> (dyn.Value, error)`
Changes made by the "set" and "map" functions are never reflected in the
input argument; they return new `dyn.Value` instances for all nodes in
the path leading up to the changed value.
## Tests
New unit tests cover all critical paths.
2024-01-24 18:38:46 +00:00
|
|
|
// Capture the value argument to return it.
|
|
|
|
out = ev
|
|
|
|
return ev, nil
|
|
|
|
},
|
|
|
|
})
|
|
|
|
return out, err
|
|
|
|
}
|