Skip to content

Commit

Permalink
initial take on lazy value
Browse files Browse the repository at this point in the history
Signed-off-by: Heinz N. Gies <[email protected]>
  • Loading branch information
Licenser committed Aug 3, 2024
1 parent b5d0fdc commit 952a4e8
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 131 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "simd-json"
version = "0.13.10"
version = "0.14.0-rc.1"
authors = ["Heinz N. Gies <[email protected]>", "Sunny Gleason"]
edition = "2021"
exclude = ["data/*", "fuzz/*"]
Expand All @@ -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 }
Expand Down
33 changes: 25 additions & 8 deletions src/value/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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:?}"),
Expand Down
18 changes: 9 additions & 9 deletions src/value/lazy/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self::Item> {
match self {
Expand All @@ -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<Value<'a, 'input>> {
pub fn get<'a>(&'a self, idx: usize) -> Option<Value<'a, 'tape, 'input>> {
match self {
Array::Tape(t) => t.get(idx).map(Value::Tape),
Array::Value(v) => v.get(idx).map(Cow::Borrowed).map(Value::Value),
Expand All @@ -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()),
Expand Down
41 changes: 21 additions & 20 deletions src/value/lazy/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,154 +3,155 @@ 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 {
self.is_null()
}
}

impl<'tape, 'input> PartialEq<bool> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<bool> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &bool) -> bool {
self.as_bool().map(|t| t.eq(other)).unwrap_or_default()
}
}

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 {
self.as_str().map(|t| t.eq(other)).unwrap_or_default()
}
}

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 {
self == *other
}
}

impl<'tape, 'input> PartialEq<String> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<String> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &String) -> bool {
self.as_str().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<i8> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<i8> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &i8) -> bool {
self.as_i8().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<i16> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<i16> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &i16) -> bool {
self.as_i16().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<i32> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<i32> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &i32) -> bool {
self.as_i32().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<i64> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<i64> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &i64) -> bool {
self.as_i64().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<i128> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<i128> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &i128) -> bool {
self.as_i128().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<u8> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<u8> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &u8) -> bool {
self.as_u8().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<u16> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<u16> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &u16) -> bool {
self.as_u16().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<u32> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<u32> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &u32) -> bool {
self.as_u32().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<u64> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<u64> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &u64) -> bool {
self.as_u64().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<usize> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<usize> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &usize) -> bool {
self.as_usize().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<u128> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<u128> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &u128) -> bool {
self.as_u128().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<f32> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<f32> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &f32) -> bool {
self.as_f32().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input> PartialEq<f64> for Value<'tape, 'input> {
impl<'borrow, 'tape, 'input> PartialEq<f64> for Value<'borrow, 'tape, 'input> {
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
fn eq(&self, other: &f64) -> bool {
self.as_f64().map(|t| t.eq(other)).unwrap_or_default()
}
}

impl<'tape, 'input, K, T, S> PartialEq<std::collections::HashMap<K, T, S>> for Value<'tape, 'input>
impl<'borrow, 'tape, 'input, K, T, S> PartialEq<std::collections::HashMap<K, T, S>>
for Value<'borrow, 'tape, 'input>
where
K: Borrow<str> + std::hash::Hash + Eq,
for<'t, 'i> T: PartialEq<Value<'t, 'i>>,
for<'b, 't, 'i> T: PartialEq<Value<'b, 't, 'i>>,
S: std::hash::BuildHasher,
{
#[cfg_attr(not(feature = "no-inline"), inline)]
Expand Down
Loading

0 comments on commit 952a4e8

Please sign in to comment.