pub mod borrowed;
pub mod owned;
pub mod tape;
pub mod lazy;
pub use self::borrowed::{
Value as BorrowedValue, to_value as to_borrowed_value,
to_value_with_buffers as to_borrowed_value_with_buffers,
};
pub use self::owned::{
Value as OwnedValue, to_value as to_owned_value,
to_value_with_buffers as to_owned_value_with_buffers,
};
use crate::{Buffers, Deserializer, Result};
use halfbrown::HashMap;
use std::hash::Hash;
use std::marker::PhantomData;
use tape::Node;
pub use value_trait::*;
#[cfg(feature = "known-key")]
pub type ObjectHasher = crate::known_key::NotSoRandomState;
#[cfg(not(feature = "known-key"))]
pub type ObjectHasher = halfbrown::DefaultHashBuilder;
pub fn deserialize<'de, Value, Key>(s: &'de mut [u8]) -> Result<Value>
where
Value: ValueBuilder<'de> + From<Vec<Value>> + From<HashMap<Key, Value, ObjectHasher>> + 'de,
Key: Hash + Eq + From<&'de str>,
{
match Deserializer::from_slice(s) {
Ok(de) => Ok(ValueDeserializer::from_deserializer(de).parse()),
Err(e) => Err(e),
}
}
pub fn deserialize_with_buffers<'de, Value, Key>(
s: &'de mut [u8],
buffers: &mut Buffers,
) -> Result<Value>
where
Value: ValueBuilder<'de> + From<Vec<Value>> + From<HashMap<Key, Value, ObjectHasher>> + 'de,
Key: Hash + Eq + From<&'de str>,
{
match Deserializer::from_slice_with_buffers(s, buffers) {
Ok(de) => Ok(ValueDeserializer::from_deserializer(de).parse()),
Err(e) => Err(e),
}
}
struct ValueDeserializer<'de, Value, Key>
where
Value: ValueBuilder<'de> + From<Vec<Value>> + From<HashMap<Key, Value, ObjectHasher>> + 'de,
Key: Hash + Eq + From<&'de str>,
{
de: Deserializer<'de>,
_marker: PhantomData<(Value, Key)>,
}
impl<'de, Value, Key> ValueDeserializer<'de, Value, Key>
where
Value: ValueBuilder<'de>
+ From<&'de str>
+ From<Vec<Value>>
+ From<HashMap<Key, Value, ObjectHasher>>
+ 'de,
Key: Hash + Eq + From<&'de str>,
{
pub fn from_deserializer(de: Deserializer<'de>) -> Self {
Self {
de,
_marker: PhantomData,
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
pub fn parse(&mut self) -> Value {
match unsafe { self.de.next_() } {
Node::Static(s) => Value::from(s),
Node::String(s) => Value::from(s),
Node::Array { len, count: _ } => self.parse_array(len),
Node::Object { len, count: _ } => self.parse_map(len),
}
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn parse_array(&mut self, len: usize) -> Value {
let mut res: Vec<Value> = Vec::with_capacity(len);
let res_ptr = res.as_mut_ptr();
unsafe {
for i in 0..len {
res_ptr.add(i).write(self.parse());
}
res.set_len(len);
}
Value::from(res)
}
#[cfg_attr(not(feature = "no-inline"), inline)]
fn parse_map(&mut self, len: usize) -> Value {
let mut res: HashMap<Key, Value, ObjectHasher> =
HashMap::with_capacity_and_hasher(len, ObjectHasher::default());
for _ in 0..len {
if let Node::String(key) = unsafe { self.de.next_() } {
#[cfg(not(feature = "value-no-dup-keys"))]
unsafe {
res.insert_nocheck(key.into(), self.parse());
};
#[cfg(feature = "value-no-dup-keys")]
res.insert(key.into(), self.parse());
} else {
unreachable!("parse_map: key needs to be a string");
}
}
Value::from(res)
}
}