Skip to main content

Crate simple_update_in

Crate simple_update_in 

Source
Expand description

Immutable nested update with structural sharing.

update_in walks a path into a JSON-like tree, transforms the value at the end, and returns a new root. Every subtree that did not change is shared by pointer, so a one-leaf edit clones only the nodes along the path.

§Model

Values are Value: maps, arrays, and scalars, plus an explicit Undefined for an absent root and for removal. Arrays and maps sit behind Rc, so Value::ptr_eq reports whether two values share a node.

§Behavior

  • Immutable. The input is never mutated. The result is a mixed clone: deep along the path, shared off it.
  • No-op identity. If the edit produces no change under SameValue, the original root is returned by the same pointer.
  • Upsert. Missing intermediates are created: a map for a key, an array for an index.
  • Type coercion. An incompatible container is replaced. A key needs a map, an index needs an array.
  • Removal. An absent updater, or an updater returning Undefined, removes the addressed key or index.
  • Predicate paths. A path step may be a predicate that selects matching children, branching the update.
  • Reserved keys. Steps equal to __proto__, constructor, or prototype make the whole call a no-op.

§Example

use simple_update_in::{update_in, Accessor, Value};

let from = Value::from_pairs([
    ("odd", Value::from_pairs([("one", 1.0.into()), ("three", 3.0.into())])),
    ("even", Value::from_pairs([("two", 2.0.into())])),
]);

let path = [Accessor::key("odd"), Accessor::key("one")];
let actual = update_in(from.clone(), &path, Some(&|v| match v {
    Value::Number(n) => Value::Number(n * 10.0),
    other => other,
}));

// The off-path subtree is shared.
let from_even = from.as_object().unwrap().get("even").unwrap().clone();
let actual_even = actual.as_object().unwrap().get("even").unwrap().clone();
assert!(from_even.ptr_eq(&actual_even));

Structs§

Map
A map that keeps keys in insertion order.

Enums§

Accessor
One step in a path.
Selector
What a predicate sees as the second argument: a map key or an array index.
Value
A JSON-like value.

Functions§

update_in
Update the value at path and return a new root.
update_in_async
Async wrapper over update_in.

Type Aliases§

Predicate
A boxed predicate: (value, key|index) -> bool.