refactor(value): migrate Value::Object to Object storage abstraction (#736)

Builds on #57. Swap Value::Object's payload from Rc<BTreeMap<Value, Value>>
to Rc<Object> and migrate all call sites to the Object API.

as_object / as_object_mut keep their names but return &Object / &mut Object.
The mutable accessor handles Rc::make_mut internally, so callers no longer
do it themselves. Object grows into_value() and From<Object> for Value.
Value's serializer now delegates to Object::serialize, dropping a duplicate
non-string-key stringification path.

RVM IterationState::Object is rewritten around ObjectCursor: O(log n)
steps over a shared Rc<Object>, no eager pair snapshot. Snapshot
independence is preserved by Rc copy-on-write; setup_next_iteration
advances the cursor inline and advance() becomes a no-op for this variant.
A new iteration_state_object_is_snapshot_independent_of_source test
covers CoW against a mutated alias.

Value::Set still wraps Rc<BTreeSet<Value>>; the matching Set abstraction
and its swap ship in follow-up PRs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Anand Krishnamoorthi
2026-06-05 18:04:37 -05:00
committed by GitHub
parent bd90453dd3
commit ed6ae465b0
30 changed files with 439 additions and 372 deletions

View File

@@ -153,6 +153,12 @@ impl Object {
self.inner.entry(key).or_insert_with(default)
}
/// Wrap into a `Value::Object`.
#[inline]
pub fn into_value(self) -> Value {
Value::Object(crate::Rc::new(self))
}
/// Create a resumable cursor over entries in implementation-defined
/// order. Stable for the lifetime of `&self`. O(1).
///
@@ -250,3 +256,10 @@ impl From<BTreeMap<Value, Value>> for Object {
Self { inner: map }
}
}
impl From<Object> for Value {
#[inline]
fn from(o: Object) -> Self {
o.into_value()
}
}