use std::{collections::HashMap, fmt};
use serde::{
de::{Deserialize, Deserializer, MapAccess, Visitor},
ser::{Serialize, SerializeMap},
};
use super::DataValue;
struct DataValueVisitor;
impl<'de> Visitor<'de> for DataValueVisitor {
type Value = DataValue;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a very special map")
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::Bool(v))
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::I64(v))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::U64(v))
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::F64(v))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::String(v.into()))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::String(v.into()))
}
#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(DataValue::Null)
}
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::F32(v))
}
fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::U8(v))
}
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::I128(v))
}
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::U128(v))
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::Bytes(v.into()))
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::Bytes(v))
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DataValue::Null)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut vec = Vec::new();
while let Ok(Some(value)) = seq.next_element() {
vec.push(value);
}
Ok(DataValue::Vec(vec))
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut map = HashMap::with_capacity(access.size_hint().unwrap_or(0));
while let Some((key, value)) = access.next_entry()? {
map.insert(key, value);
}
Ok(DataValue::Map(map))
}
}
impl<'de> Deserialize<'de> for DataValue {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(DataValueVisitor)
}
}
impl Serialize for DataValue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
DataValue::Bool(v) => serializer.serialize_bool(*v),
DataValue::I64(v) => serializer.serialize_i64(*v),
DataValue::U64(v) => serializer.serialize_u64(*v),
DataValue::F64(v) => serializer.serialize_f64(*v),
DataValue::String(v) => serializer.serialize_str(v),
DataValue::F32(v) => serializer.serialize_f32(*v),
DataValue::U8(v) => serializer.serialize_u8(*v),
DataValue::I128(v) => serializer.serialize_i128(*v),
DataValue::U128(v) => serializer.serialize_u128(*v),
DataValue::Bytes(v) => serializer.serialize_bytes(v),
DataValue::Vec(v) => v.serialize(serializer),
DataValue::Map(v) => {
let mut map = serializer.serialize_map(Some(v.len()))?;
for (k, v) in v {
map.serialize_entry(k, v)?;
}
map.end()
}
DataValue::Null => serializer.serialize_none(),
DataValue::I32(v) => serializer.serialize_i32(*v),
DataValue::U32(v) => serializer.serialize_u32(*v),
DataValue::EnumNumber(v) => serializer.serialize_i32(*v),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use rstest::*;
#[rstest]
#[case::bool(true, DataValue::Bool(true))]
#[case::i64(-42i64, DataValue::I64(-42))]
#[case::f64(42.0f64, DataValue::F64(42.0))]
#[case::str("test", DataValue::String("test".into()))]
#[case::string("test".to_string(), DataValue::String("test".into()))]
#[case::seq(vec![DataValue::I64(-1), DataValue::I64(-2)], DataValue::Vec(vec![DataValue::I64(-1), DataValue::I64(-2)]))]
#[case::map({
let mut map = HashMap::new();
map.insert("key".to_string(), DataValue::U64(42));
map
}, DataValue::Map(crate::stdhashmap!("key" => DataValue::U64(42))))]
fn test_deserialize(#[case] input: impl Into<DataValue>, #[case] expected: DataValue) {
let input = input.into();
let serialized = serde_json::to_value(&input);
assert!(serialized.is_ok(), "{:?}", serialized);
println!("{:?}", serialized);
let deserialized: Result<DataValue, _> = serde_json::from_value(serialized.unwrap());
assert!(deserialized.is_ok(), "{:?}", deserialized);
assert_eq!(deserialized.unwrap(), expected);
}
#[derive(Debug, thiserror::Error)]
enum DummyError {
#[error("Custom error: {0}")]
Custom(String),
}
impl serde::de::Error for DummyError {
#[cold]
fn custom<T: fmt::Display>(msg: T) -> Self {
Self::Custom(msg.to_string())
}
}
#[rstest]
fn test_visitor() {
let v = DataValueVisitor.visit_bool::<DummyError>(true);
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::Bool(true));
let v = DataValueVisitor.visit_i64::<DummyError>(-42);
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::I64(-42));
let v = DataValueVisitor.visit_u64::<DummyError>(42);
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::U64(42));
let v = DataValueVisitor.visit_f64::<DummyError>(42.0);
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::F64(42.0));
let v = DataValueVisitor.visit_str::<DummyError>("test");
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::String("test".into()));
let v = DataValueVisitor.visit_string::<DummyError>("test".to_string());
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::String("test".into()));
let v = DataValueVisitor.visit_f32::<DummyError>(42.0);
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::F32(42.0));
let v = DataValueVisitor.visit_u8::<DummyError>(42);
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::U8(42));
let v = DataValueVisitor.visit_i128::<DummyError>(i128::MAX);
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::I128(i128::MAX));
let v = DataValueVisitor.visit_u128::<DummyError>(u128::MAX);
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::U128(u128::MAX));
let v = DataValueVisitor.visit_bytes::<DummyError>(b"test");
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::Bytes(b"test".to_vec()));
let v = DataValueVisitor.visit_byte_buf::<DummyError>(b"test".to_vec());
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::Bytes(b"test".to_vec()));
let v = DataValueVisitor.visit_none::<DummyError>();
assert!(v.is_ok());
assert_eq!(v.unwrap(), DataValue::Null);
}
#[rstest]
fn serde_simple() {
let v: Result<Vec<DataValue>, _> = serde_json::from_str(
r#"[
253780,
0.009369421750307085,
1633222860381359,
8,
5,
true,
0.16074353018902807,
0.4461714007722576,
null,
0.3,
0.3,
0.3,
-4.660890306625259,
null,
0
]"#,
);
assert!(v.is_ok(), "{v:?}");
}
}