use serde::de::{self, DeserializeOwned, Deserializer, MapAccess, SeqAccess, Visitor};
use std::collections::HashSet;
use std::fmt;
#[cfg(feature = "simd")]
pub const BACKEND_ID: &str = "simd-json";
#[cfg(not(feature = "simd"))]
pub const BACKEND_ID: &str = "serde_json";
#[derive(Debug)]
pub(crate) struct DecodeError {
pub(crate) is_data: bool,
msg: String,
}
impl fmt::Display for DecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.msg)
}
}
impl From<serde_json::Error> for DecodeError {
fn from(e: serde_json::Error) -> Self {
DecodeError {
is_data: e.is_data(),
msg: e.to_string(),
}
}
}
#[cfg(not(feature = "simd"))]
#[inline]
pub(crate) fn decode_one<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, DecodeError> {
serde_json::from_slice(bytes).map_err(DecodeError::from)
}
#[cfg(feature = "simd")]
thread_local! {
static SIMD: std::cell::RefCell<(Vec<u8>, simd_json::Buffers)> =
std::cell::RefCell::new((Vec::new(), simd_json::Buffers::new(0)));
}
#[cfg(feature = "simd")]
#[inline]
pub(crate) fn decode_one<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, DecodeError> {
SIMD.with(|cell| {
let (buf, buffers) = &mut *cell.borrow_mut();
buf.clear();
buf.extend_from_slice(bytes);
simd_json::serde::from_slice_with_buffers::<T>(buf.as_mut_slice(), buffers).map_err(|e| {
DecodeError {
is_data: false,
msg: e.to_string(),
}
})
})
}
pub(crate) fn check_no_duplicate_keys(bytes: &[u8]) -> Result<(), DecodeError> {
serde_json::from_slice::<DupGuard>(bytes)
.map(|_| ())
.map_err(DecodeError::from)
}
struct DupGuard;
impl<'de> serde::Deserialize<'de> for DupGuard {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(DupVisitor)
}
}
struct DupVisitor;
impl<'de> Visitor<'de> for DupVisitor {
type Value = DupGuard;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("any JSON value with unique object keys")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut seen: HashSet<String> = HashSet::new();
while let Some(key) = map.next_key::<String>()? {
if !seen.insert(key.clone()) {
return Err(de::Error::custom(format!("duplicate object key `{key}`")));
}
map.next_value::<DupGuard>()?;
}
Ok(DupGuard)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
while seq.next_element::<DupGuard>()?.is_some() {}
Ok(DupGuard)
}
fn visit_bool<E>(self, _v: bool) -> Result<Self::Value, E> {
Ok(DupGuard)
}
fn visit_i64<E>(self, _v: i64) -> Result<Self::Value, E> {
Ok(DupGuard)
}
fn visit_u64<E>(self, _v: u64) -> Result<Self::Value, E> {
Ok(DupGuard)
}
fn visit_f64<E>(self, _v: f64) -> Result<Self::Value, E> {
Ok(DupGuard)
}
fn visit_str<E>(self, _v: &str) -> Result<Self::Value, E> {
Ok(DupGuard)
}
fn visit_none<E>(self) -> Result<Self::Value, E> {
Ok(DupGuard)
}
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(DupGuard)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(DupVisitor)
}
}