use std::borrow::Cow;
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use serde::de::DeserializeOwned;
#[cfg(test)]
use serde::Deserialize;
use serde::Serialize;
use crate::Result;
#[cfg(not(feature = "simd_json"))]
mod export {
pub type Value = serde_json::Value;
pub type JsonMap = serde_json::Map<String, Value>;
pub const NULL: Value = Value::Null;
pub use serde_json::{json, Error as JsonError};
}
#[cfg(feature = "simd_json")]
mod export {
pub type Value = simd_json::OwnedValue;
pub type JsonMap = simd_json::owned::Object;
pub const NULL: Value = Value::Static(simd_json::StaticNode::Null);
pub use simd_json::prelude::{
TypedContainerValue,
ValueAsContainer,
ValueAsMutContainer,
ValueAsScalar,
};
pub use simd_json::{json, Error as JsonError, StaticNode};
}
pub use export::*;
#[cfg(feature = "http")]
pub(crate) async fn decode_resp<T: serde::de::DeserializeOwned>(
resp: reqwest::Response,
) -> Result<T> {
#[cfg(not(feature = "simd_json"))]
let result = serde_json::from_slice(&resp.bytes().await?)?;
#[cfg(feature = "simd_json")]
let result = simd_json::from_slice(&mut resp.bytes().await?.to_vec())?;
Ok(result)
}
pub fn hashmap_to_json_map<H, T>(map: HashMap<T, Value, H>) -> JsonMap
where
H: BuildHasher,
T: Eq + Hash + ToString,
{
map.into_iter().map(|(k, v)| (k.to_string(), v)).collect()
}
#[allow(clippy::missing_errors_doc)]
pub fn from_str<'a, T>(s: impl Into<Cow<'a, str>>) -> Result<T>
where
T: DeserializeOwned,
{
let s = s.into();
#[cfg(not(feature = "simd_json"))]
let result = serde_json::from_str(&s)?;
#[cfg(feature = "simd_json")]
let result = simd_json::from_slice(&mut s.into_owned().into_bytes())?;
Ok(result)
}
#[allow(clippy::missing_errors_doc)]
pub fn from_slice<T>(v: &[u8]) -> Result<T>
where
T: DeserializeOwned,
{
#[cfg(not(feature = "simd_json"))]
let result = serde_json::from_slice(v)?;
#[cfg(feature = "simd_json")]
let result = simd_json::from_slice(&mut v.to_vec())?;
Ok(result)
}
#[allow(clippy::missing_errors_doc)]
pub fn from_value<T>(value: Value) -> Result<T>
where
T: DeserializeOwned,
{
#[cfg(not(feature = "simd_json"))]
let result = serde_json::from_value(value)?;
#[cfg(feature = "simd_json")]
let result = simd_json::serde::from_owned_value(value)?;
Ok(result)
}
#[allow(clippy::missing_errors_doc)]
pub fn from_reader<R, T>(rdr: R) -> Result<T>
where
R: std::io::Read,
T: DeserializeOwned,
{
#[cfg(not(feature = "simd_json"))]
let result = serde_json::from_reader(rdr)?;
#[cfg(feature = "simd_json")]
let result = simd_json::from_reader(rdr)?;
Ok(result)
}
#[allow(clippy::missing_errors_doc)]
pub fn to_string<T>(value: &T) -> Result<String>
where
T: ?Sized + Serialize,
{
#[cfg(not(feature = "simd_json"))]
let result = serde_json::to_string(value)?;
#[cfg(feature = "simd_json")]
let result = simd_json::to_string(value)?;
Ok(result)
}
#[allow(clippy::missing_errors_doc)]
pub fn to_string_pretty<T>(value: &T) -> Result<String>
where
T: ?Sized + Serialize,
{
#[cfg(not(feature = "simd_json"))]
let result = serde_json::to_string_pretty(value)?;
#[cfg(feature = "simd_json")]
let result = simd_json::to_string_pretty(value)?;
Ok(result)
}
#[allow(clippy::missing_errors_doc)]
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
where
T: ?Sized + Serialize,
{
#[cfg(not(feature = "simd_json"))]
let result = serde_json::to_vec(value)?;
#[cfg(feature = "simd_json")]
let result = simd_json::to_vec(value)?;
Ok(result)
}
#[allow(clippy::missing_errors_doc)]
pub fn to_vec_pretty<T>(value: &T) -> Result<Vec<u8>>
where
T: ?Sized + Serialize,
{
#[cfg(not(feature = "simd_json"))]
let result = serde_json::to_vec_pretty(value)?;
#[cfg(feature = "simd_json")]
let result = simd_json::to_vec_pretty(value)?;
Ok(result)
}
#[allow(clippy::missing_errors_doc)]
pub fn to_value<T>(value: T) -> Result<Value>
where
T: Serialize,
{
#[cfg(not(feature = "simd_json"))]
let result = serde_json::to_value(value)?;
#[cfg(feature = "simd_json")]
let result = simd_json::serde::to_owned_value(value)?;
Ok(result)
}
#[cfg(test)]
#[track_caller]
pub(crate) fn assert_json<T>(data: &T, json: crate::json::Value)
where
T: Serialize + for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug,
{
let serialized = to_value(data).unwrap();
assert!(
serialized == json,
"data->JSON serialization failed\nexpected: {json:?}\n got: {serialized:?}"
);
let deserialized = from_value::<T>(json).unwrap();
assert!(
&deserialized == data,
"JSON->data deserialization failed\nexpected: {data:?}\n got: {deserialized:?}"
);
}