Skip to content

Commit

Permalink
Make an Hasher parameter to the Value
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerollmops committed Dec 10, 2024
1 parent 37bc079 commit 73955ab
Showing 1 changed file with 29 additions and 7 deletions.
36 changes: 29 additions & 7 deletions src/value.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::hash::BuildHasher;

use bumpalo::Bump;
use hashbrown::DefaultHashBuilder;
use serde::de::Deserializer as _;
use serde::de::Visitor;

use serde_json::value::RawValue;

/// Represents a partially parsed JSON value referencing the underlying data.
#[derive(Debug)]
pub enum Value<'bump> {
pub enum Value<'bump, S = DefaultHashBuilder> {
/// A JSON null value.
Null,
/// A JSON boolean.
Expand All @@ -18,7 +21,7 @@ pub enum Value<'bump> {
/// A JSON array.
Array(crate::RawVec<'bump>),
/// A JSON object.
Object(crate::RawMap<'bump>),
Object(crate::RawMap<'bump, S>),
}

#[derive(Debug)]
Expand All @@ -42,16 +45,35 @@ impl<'de, 'bump: 'de> Value<'de> {
raw: &'de RawValue,
bump: &'bump Bump,
) -> Result<Value<'de>, serde_json::Error> {
raw.deserialize_any(ValueVisitor { bump })
raw.deserialize_any(ValueVisitor {
bump,
hash_builder: DefaultHashBuilder::default(),
})
}
}

impl<'de, 'bump: 'de, S: BuildHasher> Value<'de, S> {
/// Constructs a value by parsing the top level of a [`serde_json::value::RawValue`].
///
/// The resulting value will refer to the underlying JSON data as much as possible.
/// Any allocation that needs to occur (e.g., map nodes or escaped strings) will take place in the
/// provided [`bumpalo::Bump`].
pub fn from_raw_value_and_hasher(
raw: &'de RawValue,
hash_builder: S,
bump: &'bump Bump,
) -> Result<Value<'de, S>, serde_json::Error> {
raw.deserialize_any(ValueVisitor { bump, hash_builder })
}
}

struct ValueVisitor<'bump> {
struct ValueVisitor<'bump, S> {
bump: &'bump Bump,
hash_builder: S,
}

impl<'de> Visitor<'de> for ValueVisitor<'de> {
type Value = Value<'de>;
impl<'de, S: BuildHasher> Visitor<'de> for ValueVisitor<'de, S> {
type Value = Value<'de, S>;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "any valid JSON value")
Expand Down Expand Up @@ -146,7 +168,7 @@ impl<'de> Visitor<'de> for ValueVisitor<'de> {
where
A: serde::de::MapAccess<'de>,
{
let mut object = crate::RawMap::new_in(self.bump);
let mut object = crate::RawMap::with_hasher_in(self.hash_builder, self.bump);
if let Some(size_hint) = map.size_hint() {
object.reserve(size_hint);
}
Expand Down

0 comments on commit 73955ab

Please sign in to comment.