use alloc::boxed::Box;
use alloc::vec::Vec;
use super::{Object, Repr};
use crate::value::Value;
impl Object {
pub(crate) fn freeze(mut self) -> Self {
self.freeze_in_place();
self
}
#[inline]
pub fn into_value(self) -> Value {
Value::Object(crate::Rc::new(self.freeze()))
}
#[cfg(test)]
#[doc(hidden)]
pub(crate) const fn storage_variant_for_memory_diagnostics(&self) -> &'static str {
match &self.repr {
Repr::Empty => "Empty",
Repr::Frozen(_) => "Frozen",
Repr::BTree(_) => "BTree",
}
}
fn freeze_in_place(&mut self) {
match core::mem::take(&mut self.repr) {
Repr::Empty => {
self.repr = Repr::Frozen(Box::new([]));
}
Repr::Frozen(v) => {
debug_assert_sorted_dedup(&v);
self.repr = Repr::Frozen(v);
}
Repr::BTree(m) => {
let boxed = m.into_iter().collect::<Vec<_>>().into_boxed_slice();
debug_assert_sorted_dedup(&boxed);
self.repr = Repr::Frozen(boxed);
}
}
}
pub(super) fn thawed_repr(v: Box<[(Value, Value)]>) -> Repr {
debug_assert_sorted_dedup(&v);
if v.is_empty() {
Repr::Empty
} else {
Repr::BTree(Vec::from(v).into_iter().collect())
}
}
pub(super) fn thaw(&mut self) {
let repr = core::mem::take(&mut self.repr);
self.repr = match repr {
Repr::Frozen(v) => Self::thawed_repr(v),
other => other,
};
}
}
#[cfg(debug_assertions)]
fn debug_assert_sorted_dedup(v: &[(Value, Value)]) {
for pair in v.windows(2) {
debug_assert!(
pair[0].0.cmp(&pair[1].0).is_lt(),
"Object Frozen entries must be strictly sorted and deduplicated; \
TODO(Number): revisit NaN ordering/equality semantics in src/number.rs:290-316"
);
}
}
#[cfg(not(debug_assertions))]
#[inline]
fn debug_assert_sorted_dedup(_: &[(Value, Value)]) {}