simple-update-in 0.1.0

Immutable nested update with structural sharing
Documentation
  • Coverage
  • 100%
    20 out of 20 items documented3 out of 3 items with examples
  • Size
  • Source code size: 67.04 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.09 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 2s Average build duration of successful builds.
  • all releases: 2s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • hey-jj/simple-update-in
    0 0 2
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • hey-jj

simple-update-in

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 off the path is shared by pointer, so a one-leaf edit clones only the nodes along the path. If the edit changes nothing, the original root comes back by the same pointer.

Installation

[dependencies]
simple-update-in = "0.1"

Usage

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

let from = Value::from_pairs([
    ("one", Value::Number(1.0)),
    ("two", Value::Number(2.0)),
]);

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

assert_eq!(
    actual,
    Value::from_pairs([
        ("one", Value::Number(10.0)),
        ("two", Value::Number(2.0)),
    ]),
);

Behavior

  • Immutable. The input is never mutated. The result is deep along the path and shared off it.
  • No-op identity. If the edit makes no change under SameValue, the original root is returned by the same pointer. Value::ptr_eq reports this.
  • 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. Pass None as the updater, or return Value::Undefined, to remove the addressed key or index. Arrays shrink. Maps drop the key.
  • Predicate paths. A path step can be a predicate that selects matching children, branching the update across each match.
  • Reserved keys. A step equal to __proto__, constructor, or prototype makes the whole call a no-op.

SameValue

The no-op check uses the SameValue algorithm, the same one as JavaScript Object.is. NaN equals NaN, so writing NaN over NaN is a no-op. +0.0 does not equal -0.0, so writing -0.0 over 0.0 is a change.

Async

update_in_async is an async wrapper over update_in. The engine does no IO, so it resolves immediately and returns the same result. It exists so async callers can await a single entry point.

License

Licensed under the MIT license.