Skip to main content

Value

Enum Value 

Source
pub enum Value {
    Undefined,
    Null,
    Bool(bool),
    Number(f64),
    String(String),
    Array(Arc<Vec<Value>>),
    Object(Arc<IndexMap<String, Value>>),
    Text(Text),
    ListRef(Arc<ListRef>),
    MapRef(Arc<MapRef>),
}

Variants§

§

Undefined

§

Null

§

Bool(bool)

§

Number(f64)

§

String(String)

§

Array(Arc<Vec<Value>>)

Shared, not owned. The engine builds a tree by folding each finished rule’s value into its parent’s container, and with an owned container that fold copied the whole accumulated subtree – once per level, so a document nested d deep cost O(d^2). A depth-1024 document took 398 ms where TypeScript, whose values are references, took 6 ms. Behind an Arc the fold is a refcount bump and the build is linear again.

Arc rather than Rc because Value is Send + Sync and has to stay that way: Options carries Values and is shared as Arc<Options>, and a parsed value can be sent between threads today. The atomic lands only on containers, never on a Number or a String, and one refcount beats copying a map by any measure.

Mutate through Arc::make_mut, which copies only when the container is genuinely shared.

§

Object(Arc<IndexMap<String, Value>>)

§

Text(Text)

§

ListRef(Arc<ListRef>)

Shared for the reason above, and behind a pointer for the reason they always were: a ListRef is 112 bytes and a MapRef 152, and an unboxed variant sets the size of every Value, hence of every Token and every Rule. Both are niche next to the scalars and containers the parse loop moves constantly.

§

MapRef(Arc<MapRef>)

Implementations§

Source§

impl Value

Source

pub fn array(values: Vec<Value>) -> Self

Build an array value from an owned vector.

The variant holds an Arc, so that a value folded into a parent container costs a refcount rather than a copy. Constructing one still starts from an owned vector, and this is the shorthand for handing it over.

Source

pub fn object(entries: IndexMap<String, Value>) -> Self

Build an object value from an owned map. See Value::array.

Source

pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>>

The array behind this value, ready to write to, or None when it is not an array.

Copies the contents first if anything else still shares them, so a write through this handle is never seen by another holder. That copy is the whole price of sharing, and it is paid only when a value is mutated after being handed on – which the tree build, which only ever folds a finished value upwards, never does.

Source

pub fn as_object_mut(&mut self) -> Option<&mut IndexMap<String, Value>>

The map behind this value, ready to write to, or None when it is not an object. See Value::as_array_mut.

Source

pub fn is_undefined(&self) -> bool

Source

pub fn is_null(&self) -> bool

Source

pub fn unwrap_undefined(self) -> Value

Replace every Undefined in the tree with Null.

Iterative on purpose. The recursive form walked the document with the call stack, one frame per nesting level, and a strict-JSON parse of [[[...]]] overflowed the default 8 MiB main-thread stack – an uncatchable abort – somewhere between 8,000 and 16,000 levels in a release build and between 2,000 and 4,000 in a debug build. TypeScript’s parse loop is iterative (ts/src/parser.ts, while (norule !== rule ...)), so this walk was the only part of a parse whose stack use grew with the document’s depth. tests/deep_nesting_test.rs pins it.

The walk is also skipped when the tree holds no Undefined, the common case: rebuilding every container would otherwise copy each level, since the parse’s root node still shares them.

Source

pub fn to_json(&self) -> Value

Source

pub fn from_json(v: &Value) -> Self

Source

pub fn deep_equal(&self, other: &Value) -> bool

Trait Implementations§

Source§

impl Clone for Value

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Value

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Value

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for Value

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Value

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for Value

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Value

Auto Trait Implementations§

§

impl Freeze for Value

§

impl RefUnwindSafe for Value

§

impl Send for Value

§

impl Sync for Value

§

impl Unpin for Value

§

impl UnsafeUnpin for Value

§

impl UnwindSafe for Value

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.