From 952a4e8cd0c91792f226cf6c2f64107698f2ff0a Mon Sep 17 00:00:00 2001 From: "Heinz N. Gies" Date: Sat, 3 Aug 2024 14:19:12 +0200 Subject: [PATCH] initial take on lazy value Signed-off-by: Heinz N. Gies --- Cargo.toml | 4 +- src/value/lazy.rs | 33 ++++++++++++---- src/value/lazy/array.rs | 18 ++++----- src/value/lazy/cmp.rs | 41 ++++++++++---------- src/value/lazy/from.rs | 67 +++++++++++++++++++------------- src/value/lazy/object.rs | 38 +++++++++--------- src/value/lazy/trait_impls.rs | 72 +++++++++++++++++++---------------- src/value/tape.rs | 6 ++- src/value/tape/trait_impls.rs | 22 +++++------ 9 files changed, 170 insertions(+), 131 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b0fa2ae2..0a8db41d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "simd-json" -version = "0.13.10" +version = "0.14.0-rc.1" authors = ["Heinz N. Gies ", "Sunny Gleason"] edition = "2021" exclude = ["data/*", "fuzz/*"] @@ -20,7 +20,7 @@ simdutf8 = { version = "0.1.4", features = ["public_imp", "aarch64_neon"] } lexical-core = { version = "0.8", features = ["format"] } beef = { version = "0.5", optional = true } halfbrown = "0.2" -value-trait = { version = "0.9" } +value-trait = { version = "0.9.0-rc.1" } # ahash known key once_cell = { version = "1.17", optional = true } ahash = { version = "0.8", optional = true } diff --git a/src/value/lazy.rs b/src/value/lazy.rs index 64d5c34f..48bf9dfe 100644 --- a/src/value/lazy.rs +++ b/src/value/lazy.rs @@ -38,24 +38,41 @@ pub use object::Object; /// performed it will stay a tape. If a mutating operation is performed it will upgrade to a borrowed /// value. #[derive(Clone, Debug, PartialEq)] -pub enum Value<'tape, 'input> -where - 'input: 'tape, -{ +pub enum Value<'borrow, 'tape, 'input> { /// tape variant Tape(tape::Value<'tape, 'input>), /// borrowed variant - Value(Cow<'tape, borrowed::Value<'input>>), + Value(Cow<'borrow, borrowed::Value<'input>>), } -impl Default for Value<'static, '_> { +impl Default for Value<'static, 'static, '_> { #[cfg_attr(not(feature = "no-inline"), inline)] fn default() -> Self { Value::Value(Cow::Owned(borrowed::Value::default())) } } -impl<'tape, 'input> Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> { + /// turns the lazy value into a borrowed value + #[must_use] + pub fn into_value(self) -> borrowed::Value<'input> { + match self { + Value::Tape(tape) => { + let value = super::borrowed::BorrowSliceDeserializer::from_tape(tape.0).parse(); + value + } + Value::Value(value) => value.into_owned(), + } + } + /// extends the Value COW is owned + #[must_use] + pub fn into_owned<'snot>(self) -> Value<'snot, 'tape, 'input> { + match self { + Value::Tape(tape) => Value::Tape(tape), + Value::Value(Cow::Owned(value)) => Value::Value(Cow::Owned(value)), + Value::Value(Cow::Borrowed(value)) => Value::Value(Cow::Owned(value.clone())), + } + } /// returns true when the current representation is a tape #[must_use] pub fn is_tape(&self) -> bool { @@ -109,7 +126,7 @@ impl<'tape, 'input> Value<'tape, 'input> { } #[cfg(not(tarpaulin_include))] -impl<'tape, 'value> fmt::Display for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> fmt::Display for Value<'borrow, 'tape, 'value> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match &self { Value::Tape(tape) => write!(f, "{tape:?}"), diff --git a/src/value/lazy/array.rs b/src/value/lazy/array.rs index 3c985b3b..ab82c20a 100644 --- a/src/value/lazy/array.rs +++ b/src/value/lazy/array.rs @@ -5,20 +5,20 @@ use crate::{borrowed, tape}; #[derive(Clone)] /// Wrapper around the tape that allows interacting with it via a `Array`-like API. -pub enum Array<'tape, 'input> { +pub enum Array<'borrow, 'tape, 'input> { /// Tape variant Tape(tape::Array<'tape, 'input>), /// Value variant - Value(&'tape borrowed::Array<'input>), + Value(&'borrow borrowed::Array<'input>), } -pub enum ArrayIter<'tape, 'input> { +pub enum ArrayIter<'borrow, 'tape, 'input> { Tape(tape::array::Iter<'tape, 'input>), - Value(std::slice::Iter<'tape, borrowed::Value<'input>>), + Value(std::slice::Iter<'borrow, borrowed::Value<'input>>), } -impl<'tape, 'input> Iterator for ArrayIter<'tape, 'input> { - type Item = Value<'tape, 'input>; +impl<'borrow, 'tape, 'input> Iterator for ArrayIter<'borrow, 'tape, 'input> { + type Item = Value<'borrow, 'tape, 'input>; fn next(&mut self) -> Option { match self { @@ -29,12 +29,12 @@ impl<'tape, 'input> Iterator for ArrayIter<'tape, 'input> { } // value_trait::Array for -impl<'tape, 'input> Array<'tape, 'input> { +impl<'borrow, 'tape, 'input> Array<'borrow, 'tape, 'input> { /// Gets a ref to a value based on n index, returns `None` if the /// current Value isn't an Array or doesn't contain the index /// it was asked for. #[must_use] - pub fn get<'a>(&'a self, idx: usize) -> Option> { + pub fn get<'a>(&'a self, idx: usize) -> Option> { match self { Array::Tape(t) => t.get(idx).map(Value::Tape), Array::Value(v) => v.get(idx).map(Cow::Borrowed).map(Value::Value), @@ -43,7 +43,7 @@ impl<'tape, 'input> Array<'tape, 'input> { /// Iterates over the values paris #[allow(clippy::pedantic)] // we want into_iter_without_iter but that lint doesn't exist in older clippy #[must_use] - pub fn iter<'i>(&'i self) -> ArrayIter<'i, 'input> { + pub fn iter<'i>(&'i self) -> ArrayIter<'i, 'tape, 'input> { match self { Array::Tape(t) => ArrayIter::Tape(t.iter()), Array::Value(v) => ArrayIter::Value(v.iter()), diff --git a/src/value/lazy/cmp.rs b/src/value/lazy/cmp.rs index 01f10b62..4e54998a 100644 --- a/src/value/lazy/cmp.rs +++ b/src/value/lazy/cmp.rs @@ -3,7 +3,7 @@ use value_trait::{base::ValueAsScalar, derived::TypedScalarValue}; use super::Value; -impl<'tape, 'input> PartialEq<()> for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq<()> for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, _other: &()) -> bool { @@ -11,7 +11,7 @@ impl<'tape, 'input> PartialEq<()> for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &bool) -> bool { @@ -19,7 +19,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &str) -> bool { @@ -27,7 +27,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq<&str> for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq<&str> for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &&str) -> bool { @@ -35,7 +35,7 @@ impl<'tape, 'input> PartialEq<&str> for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &String) -> bool { @@ -43,7 +43,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &i8) -> bool { @@ -51,7 +51,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &i16) -> bool { @@ -59,7 +59,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &i32) -> bool { @@ -67,7 +67,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &i64) -> bool { @@ -75,7 +75,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &i128) -> bool { @@ -83,7 +83,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &u8) -> bool { @@ -91,7 +91,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &u16) -> bool { @@ -99,7 +99,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &u32) -> bool { @@ -107,7 +107,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &u64) -> bool { @@ -115,7 +115,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &usize) -> bool { @@ -123,7 +123,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &u128) -> bool { @@ -131,7 +131,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &f32) -> bool { @@ -139,7 +139,7 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input> PartialEq for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> PartialEq for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn eq(&self, other: &f64) -> bool { @@ -147,10 +147,11 @@ impl<'tape, 'input> PartialEq for Value<'tape, 'input> { } } -impl<'tape, 'input, K, T, S> PartialEq> for Value<'tape, 'input> +impl<'borrow, 'tape, 'input, K, T, S> PartialEq> + for Value<'borrow, 'tape, 'input> where K: Borrow + std::hash::Hash + Eq, - for<'t, 'i> T: PartialEq>, + for<'b, 't, 'i> T: PartialEq>, S: std::hash::BuildHasher, { #[cfg_attr(not(feature = "no-inline"), inline)] diff --git a/src/value/lazy/from.rs b/src/value/lazy/from.rs index 3531bf41..f82f29f0 100644 --- a/src/value/lazy/from.rs +++ b/src/value/lazy/from.rs @@ -2,7 +2,16 @@ use super::Value; use crate::StaticNode; use crate::{borrowed, cow::Cow}; use std::borrow::Cow as StdCow; -impl<'tape, 'value> From for Value<'tape, 'value> { + +impl<'borrow, 'tape, 'value> From> for Value<'borrow, 'tape, 'value> { + #[cfg_attr(not(feature = "no-inline"), inline)] + #[must_use] + fn from(v: borrowed::Value<'value>) -> Self { + Value::Value(StdCow::Owned(v)) + } +} + +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: StaticNode) -> Self { @@ -10,7 +19,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value, T> From> for Value<'tape, 'value> +impl<'borrow, 'tape, 'value, T> From> for Value<'borrow, 'tape, 'value> where borrowed::Value<'value>: From>, { @@ -21,7 +30,7 @@ where } } /********* str_ **********/ -impl<'tape, 'value> From<&'value str> for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From<&'value str> for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: &'value str) -> Self { @@ -30,7 +39,7 @@ impl<'tape, 'value> From<&'value str> for Value<'tape, 'value> { } #[cfg(feature = "beef")] -impl<'tape, 'value> From> for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From> for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: std::borrow::Cow<'value, str>) -> Self { @@ -39,7 +48,7 @@ impl<'tape, 'value> From> for Value<'tape, 'value> } #[cfg(not(feature = "beef"))] -impl<'tape, 'value> From> for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From> for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: std::borrow::Cow<'value, str>) -> Self { @@ -48,7 +57,7 @@ impl<'tape, 'value> From> for Value<'tape, 'value> } #[cfg(feature = "beef")] -impl<'tape, 'value> From> for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From> for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: beef::lean::Cow<'value, str>) -> Self { @@ -56,7 +65,7 @@ impl<'tape, 'value> From> for Value<'tape, 'value> } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: String) -> Self { @@ -65,14 +74,14 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } /********* atoms **********/ -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: bool) -> Self { Value::Value(StdCow::Owned(borrowed::Value::from(v))) } } -impl<'tape, 'value> From<()> for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From<()> for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: ()) -> Self { @@ -81,7 +90,7 @@ impl<'tape, 'value> From<()> for Value<'tape, 'value> { } /********* i_ **********/ -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: i8) -> Self { @@ -89,7 +98,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: i16) -> Self { @@ -97,7 +106,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: i32) -> Self { @@ -105,7 +114,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: i64) -> Self { @@ -114,7 +123,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } #[cfg(feature = "128bit")] -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: i128) -> Self { @@ -123,7 +132,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } /********* u_ **********/ -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: u8) -> Self { @@ -131,7 +140,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: u16) -> Self { @@ -139,7 +148,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: u32) -> Self { @@ -147,7 +156,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: u64) -> Self { @@ -156,7 +165,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } #[cfg(feature = "128bit")] -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: u128) -> Self { @@ -164,7 +173,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: usize) -> Self { @@ -173,7 +182,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } /********* f_ **********/ -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: f32) -> Self { @@ -181,7 +190,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value> From for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: f64) -> Self { @@ -189,7 +198,7 @@ impl<'tape, 'value> From for Value<'tape, 'value> { } } -impl<'tape, 'value, S> From> for Value<'tape, 'value> +impl<'borrow, 'tape, 'value, S> From> for Value<'borrow, 'tape, 'value> where borrowed::Value<'value>: From>, { @@ -200,7 +209,9 @@ where } } -impl<'tape, 'value, V: Into>> FromIterator for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value, V: Into>> FromIterator + for Value<'borrow, 'tape, 'value> +{ #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from_iter>(v: I) -> Self { @@ -208,8 +219,8 @@ impl<'tape, 'value, V: Into>> FromIterator for Value< } } -impl<'tape, 'value, K: Into>, V: Into>> - FromIterator<(K, V)> for Value<'tape, 'value> +impl<'borrow, 'tape, 'value, K: Into>, V: Into>> + FromIterator<(K, V)> for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] @@ -218,7 +229,9 @@ impl<'tape, 'value, K: Into>, V: Into>> } } -impl<'tape, 'value> From> for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> From> + for Value<'borrow, 'tape, 'value> +{ #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn from(v: crate::borrowed::Object<'value>) -> Self { diff --git a/src/value/lazy/object.rs b/src/value/lazy/object.rs index 282281ac..7720440a 100644 --- a/src/value/lazy/object.rs +++ b/src/value/lazy/object.rs @@ -8,38 +8,38 @@ use crate::{borrowed, tape}; /// Wrapper around the tape that allows interacting with it via a `Object`-like API. -pub enum Object<'tape, 'input> { +pub enum Object<'borrow, 'tape, 'input> { /// Tape variant Tape(tape::Object<'tape, 'input>), /// Value variant - Value(&'tape borrowed::Object<'input>), + Value(&'borrow borrowed::Object<'input>), } -pub enum Iter<'tape, 'input> { +pub enum Iter<'borrow, 'tape, 'input> { /// Tape variant Tape(tape::object::Iter<'tape, 'input>), /// Value variant - Value(halfbrown::Iter<'tape, crate::cow::Cow<'input, str>, borrowed::Value<'input>>), + Value(halfbrown::Iter<'borrow, crate::cow::Cow<'input, str>, borrowed::Value<'input>>), } -pub enum Keys<'tape, 'input> { +pub enum Keys<'borrow, 'tape, 'input> { /// Tape variant Tape(tape::object::Keys<'tape, 'input>), /// Value variant - Value(halfbrown::Keys<'tape, crate::cow::Cow<'input, str>, borrowed::Value<'input>>), + Value(halfbrown::Keys<'borrow, crate::cow::Cow<'input, str>, borrowed::Value<'input>>), } -pub enum Values<'tape, 'input> { +pub enum Values<'borrow, 'tape, 'input> { /// Tape variant Tape(tape::object::Values<'tape, 'input>), /// Value variant - Value(halfbrown::Values<'tape, crate::cow::Cow<'input, str>, borrowed::Value<'input>>), + Value(halfbrown::Values<'borrow, crate::cow::Cow<'input, str>, borrowed::Value<'input>>), } //value_trait::Object for -impl<'tape, 'input> Object<'tape, 'input> { +impl<'borrow, 'tape, 'input> Object<'borrow, 'tape, 'input> { /// Gets a ref to a value based on a key, returns `None` if the /// current Value isn't an Object or doesn't contain the key /// it was asked for. #[must_use] - pub fn get<'a, Q>(&'a self, k: &Q) -> Option> + pub fn get<'a, Q>(&'a self, k: &Q) -> Option> where str: Borrow, for<'b> crate::cow::Cow<'b, str>: Borrow, @@ -54,7 +54,7 @@ impl<'tape, 'input> Object<'tape, 'input> { /// Iterates over the key value paris #[allow(clippy::pedantic)] // we want into_iter_without_iter but that lint doesn't exist in older clippy #[must_use] - pub fn iter<'i>(&'i self) -> Iter<'i, 'input> { + pub fn iter<'i>(&'i self) -> Iter<'i, 'tape, 'input> { match self { Object::Tape(t) => Iter::Tape(t.iter()), Object::Value(v) => Iter::Value(v.iter()), @@ -63,7 +63,7 @@ impl<'tape, 'input> Object<'tape, 'input> { /// Iterates over the keys #[must_use] - pub fn keys<'i>(&'i self) -> Keys<'i, 'input> { + pub fn keys<'i>(&'i self) -> Keys<'i, 'tape, 'input> { match self { Object::Tape(t) => Keys::Tape(t.keys()), Object::Value(v) => Keys::Value(v.keys()), @@ -72,7 +72,7 @@ impl<'tape, 'input> Object<'tape, 'input> { /// Iterates over the values #[must_use] - pub fn values<'i>(&'i self) -> Values<'i, 'input> { + pub fn values<'i>(&'i self) -> Values<'i, 'tape, 'input> { match self { Object::Tape(t) => Values::Tape(t.values()), Object::Value(v) => Values::Value(v.values()), @@ -103,8 +103,8 @@ impl<'tape, 'input> Object<'tape, 'input> { // } // } -impl<'tape, 'input> Iterator for Iter<'tape, 'input> { - type Item = (&'tape str, Value<'tape, 'input>); +impl<'borrow, 'tape, 'input> Iterator for Iter<'borrow, 'tape, 'input> { + type Item = (&'borrow str, Value<'borrow, 'tape, 'input>); fn next(&mut self) -> Option { match self { @@ -116,8 +116,8 @@ impl<'tape, 'input> Iterator for Iter<'tape, 'input> { } } -impl<'tape, 'input> Iterator for Keys<'tape, 'input> { - type Item = &'tape str; +impl<'borrow, 'tape, 'input> Iterator for Keys<'borrow, 'tape, 'input> { + type Item = &'borrow str; fn next(&mut self) -> Option { match self { Keys::Tape(t) => t.next(), @@ -126,8 +126,8 @@ impl<'tape, 'input> Iterator for Keys<'tape, 'input> { } } -impl<'tape, 'input> Iterator for Values<'tape, 'input> { - type Item = Value<'tape, 'input>; +impl<'borrow, 'tape, 'input> Iterator for Values<'borrow, 'tape, 'input> { + type Item = Value<'borrow, 'tape, 'input>; fn next(&mut self) -> Option { match self { Values::Tape(t) => t.next().map(Value::Tape), diff --git a/src/value/lazy/trait_impls.rs b/src/value/lazy/trait_impls.rs index 39ec3885..75514b00 100644 --- a/src/value/lazy/trait_impls.rs +++ b/src/value/lazy/trait_impls.rs @@ -10,20 +10,23 @@ use value_trait::{ ValueAsScalar, ValueIntoString, Writable, }, derived::{ - ValueArrayTryAccess, ValueObjectAccessAsArray as _, ValueObjectAccessAsObject as _, ValueObjectAccessAsScalar, ValueObjectAccessTryAsArray as _, ValueObjectAccessTryAsObject as _, ValueObjectAccessTryAsScalar, ValueObjectTryAccess, ValueTryAsScalar + ValueArrayTryAccess, ValueObjectAccessAsArray as _, ValueObjectAccessAsObject as _, + ValueObjectAccessAsScalar, ValueObjectAccessTryAsArray as _, + ValueObjectAccessTryAsObject as _, ValueObjectAccessTryAsScalar, ValueObjectTryAccess, + ValueTryAsScalar, }, TryTypeError, ValueBuilder, ValueType, }; -use crate::borrowed; +use crate::{borrowed, tape}; use super::{Array, Object, Value}; -impl<'value> ValueBuilder<'value> for Value<'static, 'value> { +impl<'value> ValueBuilder<'value> for Value<'static, 'static, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn null() -> Self { - Value::Value(Cow::Owned(borrowed::Value::null())) + Value::Tape(tape::Value::null()) } #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] @@ -38,7 +41,7 @@ impl<'value> ValueBuilder<'value> for Value<'static, 'value> { } // TypedContainerValue -impl<'tape, 'input> Value<'tape, 'input> +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> where 'input: 'tape, { @@ -55,7 +58,7 @@ where } } -impl<'tape, 'value> ValueAsScalar for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> ValueAsScalar for Value<'borrow, 'tape, 'value> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn as_null(&self) -> Option<()> { @@ -138,7 +141,7 @@ impl<'tape, 'value> ValueAsScalar for Value<'tape, 'value> { } } -impl<'tape, 'value> ValueIntoString for Value<'tape, 'value> { +impl<'borrow, 'tape, 'value> ValueIntoString for Value<'borrow, 'tape, 'value> { type String = Cow<'value, str>; fn into_string(self) -> Option<::String> { @@ -191,7 +194,7 @@ impl<'tape, 'value> ValueIntoString for Value<'tape, 'value> { // } // } -impl<'tape, 'input> TypedValue for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> TypedValue for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] fn value_type(&self) -> ValueType { @@ -203,7 +206,7 @@ impl<'tape, 'input> TypedValue for Value<'tape, 'input> { } // TryValueObjectAccess -impl<'tape, 'input> Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> { // type Key = &str; // type Target = Value<'tape, 'input>; @@ -211,7 +214,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// current Value isn't an Object, returns `None` if the key isn't in the object /// # Errors /// if the value is not an object - pub fn try_get(&self, k: &Q) -> Result>, TryTypeError> + pub fn try_get(&self, k: &Q) -> Result>, TryTypeError> where str: Borrow + Hash + Eq, for<'b> crate::cow::Cow<'b, str>: Borrow, @@ -225,7 +228,7 @@ impl<'tape, 'input> Value<'tape, 'input> { } //TryValueArrayAccess -impl<'tape, 'input> Value<'tape, 'input> +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> where 'input: 'tape, { @@ -233,7 +236,7 @@ where /// current value isn't an Array, returns `None` if the index is out of bounds /// # Errors /// if the requested type doesn't match the actual type or the value is not an object - pub fn try_get_idx(&self, i: usize) -> Result>, TryTypeError> { + pub fn try_get_idx(&self, i: usize) -> Result>, TryTypeError> { match self { Value::Tape(tape) => Ok(tape.try_get_idx(i)?.map(Value::Tape)), Value::Value(value) => Ok(value.try_get_idx(i)?.map(Cow::Borrowed).map(Value::Value)), @@ -242,7 +245,7 @@ where } // impl<'tape, 'value> ValueAsContainer for Value<'tape, 'value> { -impl<'tape, 'input> Value<'tape, 'input> +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> where 'input: 'tape, { @@ -252,7 +255,7 @@ where /// Tries to represent the value as an array and returns a reference to it #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] - pub fn as_array(&self) -> Option> { + pub fn as_array(&self) -> Option> { match self { Value::Tape(tape) => tape.as_array().map(Array::Tape), Value::Value(value) => value.as_array().map(Array::Value), @@ -262,7 +265,7 @@ where /// Tries to represent the value as an array and returns a reference to it #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] - pub fn as_object(&self) -> Option> { + pub fn as_object(&self) -> Option> { match self { Value::Tape(tape) => tape.as_object().map(Object::Tape), Value::Value(value) => value.as_object().map(Object::Value), @@ -270,7 +273,7 @@ where } } -impl<'tape, 'input> ValueAsMutArray for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> ValueAsMutArray for Value<'borrow, 'tape, 'input> { type Array = Vec>; #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] @@ -278,7 +281,7 @@ impl<'tape, 'input> ValueAsMutArray for Value<'tape, 'input> { self.as_mut().as_array_mut() } } -impl<'tape, 'input> ValueAsMutObject for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> ValueAsMutObject for Value<'borrow, 'tape, 'input> { type Object = super::borrowed::Object<'input>; #[cfg_attr(not(feature = "no-inline"), inline)] #[must_use] @@ -288,11 +291,11 @@ impl<'tape, 'input> ValueAsMutObject for Value<'tape, 'input> { } // ContainerValueTryAs (needed as we don't have ValueAsContainer) -impl<'tape, 'input> Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> { /// Tries to represent the value as an array and returns a reference to it /// # Errors /// if the requested type doesn't match the actual type - pub fn try_as_array(&self) -> Result, TryTypeError> { + pub fn try_as_array(&self) -> Result, TryTypeError> { self.as_array().ok_or(TryTypeError { expected: ValueType::Array, got: self.value_type(), @@ -302,7 +305,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// Tries to represent the value as an object and returns a reference to it /// # Errors /// if the requested type doesn't match the actual type - pub fn try_as_object(&self) -> Result, TryTypeError> { + pub fn try_as_object(&self) -> Result, TryTypeError> { self.as_object().ok_or(TryTypeError { expected: ValueType::Object, got: self.value_type(), @@ -310,12 +313,12 @@ impl<'tape, 'input> Value<'tape, 'input> { } } // ValueObjectAccess (needed as we don't have ValueAsContainer ) and can't return references -impl<'tape, 'input> Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> { /// Gets a ref to a value based on a key, returns `None` if the /// current Value isn't an Object or doesn't contain the key /// it was asked for. #[must_use] - pub fn get(&self, k: &Q) -> Option> + pub fn get<'k, Q>(&self, k: &'k Q) -> Option> where str: Borrow, for<'a> crate::cow::Cow<'a, str>: Borrow, @@ -349,12 +352,12 @@ impl<'tape, 'input> Value<'tape, 'input> { } // ValueArrayAccess (needed as we don't have ValueAsContainer) -impl<'tape, 'input> Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> { /// Gets a ref to a value based on n index, returns `None` if the /// current Value isn't an Array or doesn't contain the index /// it was asked for. #[must_use] - pub fn get_idx(&self, i: usize) -> Option> { + pub fn get_idx(&self, i: usize) -> Option> { match self { Value::Tape(tape) => tape.get_idx(i).map(Value::Tape), Value::Value(value) => value @@ -367,7 +370,7 @@ impl<'tape, 'input> Value<'tape, 'input> { } // impl<'tape, 'input> ValueObjectAccessAsScalar for Value<'tape, 'input> -impl<'tape, 'input> Value<'tape, 'input> +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> where 'input: 'tape, { @@ -539,10 +542,10 @@ where } // ValueObjectContainerAccess -impl<'tape, 'input> Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> { /// Tries to get an element of an object as a array #[must_use] - pub fn get_array(&self, k: &Q) -> Option> + pub fn get_array(&self, k: &Q) -> Option> where str: Borrow, for<'a> crate::cow::Cow<'a, str>: Borrow, @@ -556,7 +559,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// Tries to get an element of an object as a object #[must_use] - pub fn get_object(&self, k: &Q) -> Option> + pub fn get_object(&self, k: &Q) -> Option> where str: Borrow, for<'a> crate::cow::Cow<'a, str>: Borrow, @@ -569,12 +572,12 @@ impl<'tape, 'input> Value<'tape, 'input> { } } // TryValueObjectContainerAccess -impl<'tape, 'input> Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> { /// Tries to get an element of an object as an array, returns /// an error if it isn't a array /// # Errors /// if the requested type doesn't match the actual type or the value is not an object - pub fn try_get_array(&self, k: &Q) -> Result>, TryTypeError> + pub fn try_get_array(&self, k: &Q) -> Result>, TryTypeError> where str: Borrow, for<'a> crate::cow::Cow<'a, str>: Borrow, @@ -591,7 +594,10 @@ impl<'tape, 'input> Value<'tape, 'input> { /// /// # Errors /// if the requested type doesn't match the actual type or the value is not an object - pub fn try_get_object(&self, k: &Q) -> Result>, TryTypeError> + pub fn try_get_object( + &self, + k: &Q, + ) -> Result>, TryTypeError> where str: Borrow, for<'a> crate::cow::Cow<'a, str>: Borrow, @@ -605,7 +611,7 @@ impl<'tape, 'input> Value<'tape, 'input> { } // impl<'tape, 'input> ValueObjectAccessTryAsScalar for Value<'tape, 'input> { -impl<'tape, 'input> Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Value<'borrow, 'tape, 'input> { /// Tries to get an element of an object as a bool, returns /// an error if it isn't bool /// # Errors @@ -819,7 +825,7 @@ impl<'tape, 'input> Value<'tape, 'input> { } } -impl<'tape, 'input> Writable for Value<'tape, 'input> { +impl<'borrow, 'tape, 'input> Writable for Value<'borrow, 'tape, 'input> { #[cfg_attr(not(feature = "no-inline"), inline)] fn encode(&self) -> String { match self { diff --git a/src/value/tape.rs b/src/value/tape.rs index 1f9f6af7..c9e0c707 100644 --- a/src/value/tape.rs +++ b/src/value/tape.rs @@ -43,11 +43,13 @@ where 'input: 'tape; impl Value<'static, 'static> { - const NULL: [Node<'static>; 1] = [Node::Static(StaticNode::Null)]; + const NULL_TAPE: [Node<'static>; 1] = [Node::Static(StaticNode::Null)]; + /// A static null value + pub const NULL: Value<'static, 'static> = Value(&Self::NULL_TAPE); /// Creates tape value representing a null value #[must_use] pub const fn null() -> Self { - Self(&Self::NULL) + Self::NULL } } diff --git a/src/value/tape/trait_impls.rs b/src/value/tape/trait_impls.rs index c9621451..126ae616 100644 --- a/src/value/tape/trait_impls.rs +++ b/src/value/tape/trait_impls.rs @@ -149,7 +149,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// current Value isn't an Object, returns `None` if the key isn't in the object /// # Errors /// if the value is not an object - pub fn try_get(&self, k: &Q) -> Result>, TryTypeError> + pub fn try_get(&self, k: &Q) -> Result>, TryTypeError> where str: Borrow + Hash + Eq, Q: ?Sized + Hash + Eq + Ord, @@ -167,7 +167,7 @@ where /// current value isn't an Array, returns `None` if the index is out of bounds /// # Errors /// if the requested type doesn't match the actual type or the value is not an object - pub fn try_get_idx(&self, i: usize) -> Result>, TryTypeError> { + pub fn try_get_idx(&self, i: usize) -> Result>, TryTypeError> { Ok(self.try_as_array()?.get(i)) } } @@ -179,7 +179,7 @@ where { /// Tries to represent the value as an array and returns a reference to it #[must_use] - pub fn as_array(&self) -> Option> { + pub fn as_array(&self) -> Option> { if let Some(Node::Array { count, .. }) = self.0.first() { // we add one element as we want to keep the array header let count = *count + 1; @@ -191,7 +191,7 @@ where /// Tries to represent the value as an array and returns a reference to it #[must_use] - pub fn as_object(&self) -> Option> { + pub fn as_object(&self) -> Option> { if let Some(Node::Object { count, .. }) = self.0.first() { // we add one element as we want to keep the object header let count = *count + 1; @@ -207,7 +207,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// Tries to represent the value as an array and returns a reference to it /// # Errors /// if the requested type doesn't match the actual type - pub fn try_as_array(&self) -> Result, TryTypeError> { + pub fn try_as_array(&self) -> Result, TryTypeError> { self.as_array().ok_or(TryTypeError { expected: ValueType::Array, got: self.value_type(), @@ -217,7 +217,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// Tries to represent the value as an object and returns a reference to it /// # Errors /// if the requested type doesn't match the actual type - pub fn try_as_object(&self) -> Result, TryTypeError> { + pub fn try_as_object(&self) -> Result, TryTypeError> { self.as_object().ok_or(TryTypeError { expected: ValueType::Object, got: self.value_type(), @@ -230,7 +230,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// current Value isn't an Object or doesn't contain the key /// it was asked for. #[must_use] - pub fn get(&self, k: &Q) -> Option> + pub fn get(&self, k: &Q) -> Option> where str: Borrow + Hash + Eq, Q: ?Sized + Hash + Eq + Ord, @@ -252,7 +252,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// current Value isn't an Array or doesn't contain the index /// it was asked for. #[must_use] - pub fn get_idx(&self, i: usize) -> Option> { + pub fn get_idx(&self, i: usize) -> Option> { self.as_array().and_then(|a| a.get(i)) } } @@ -406,7 +406,7 @@ where impl<'tape, 'input> Value<'tape, 'input> { /// Tries to get an element of an object as a array #[must_use] - pub fn get_array(&self, k: &Q) -> Option> + pub fn get_array(&self, k: &Q) -> Option> where str: Borrow + Hash + Eq, Q: ?Sized + Hash + Eq + Ord, @@ -432,7 +432,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// Tries to get an element of an object as a object #[must_use] - pub fn get_object(&self, k: &Q) -> Option> + pub fn get_object(&self, k: &Q) -> Option> where str: Borrow + Hash + Eq, Q: ?Sized + Hash + Eq + Ord, @@ -491,7 +491,7 @@ impl<'tape, 'input> Value<'tape, 'input> { /// /// # Errors /// if the requested type doesn't match the actual type or the value is not an object - pub fn try_get_object(&self, k: &Q) -> Result>, TryTypeError> + pub fn try_get_object(&self, k: &Q) -> Result>, TryTypeError> where str: Borrow + Hash + Eq, Q: ?Sized + Hash + Eq + Ord,