use crate::Value;
use serde::Deserialize;
pub struct OptionalValue;
impl<'de> serde_with::DeserializeAs<'de, Option<Value>> for OptionalValue {
fn deserialize_as<D>(deserializer: D) -> Result<Option<Value>, D::Error>
where
D: serde::de::Deserializer<'de>,
{
Ok(Option::<Value>::deserialize(deserializer)?.or(Some(Value::Null)))
}
}
impl serde_with::SerializeAs<Option<Value>> for OptionalValue {
fn serialize_as<S>(source: &Option<Value>, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::Serialize;
match source {
None => serializer.serialize_none(),
Some(v) => v.serialize(serializer),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Result;
use serde_json::{Value, json};
use serde_with::{DeserializeAs, SerializeAs};
use test_case::test_case;
#[test_case(json!(null))]
#[test_case(json!("abc"))]
#[test_case(json!(1))]
#[test_case(json!([1, 2, "a"]))]
#[test_case(json!({"a": [1, 2, "a"], "b": null}))]
fn deser_and_ser(input: Value) -> Result<()> {
let got = OptionalValue::deserialize_as(input.clone())?;
assert_eq!(got, Some(input));
let serialized = OptionalValue::serialize_as(&got, serde_json::value::Serializer)?;
assert_eq!(serialized, json!(got));
Ok(())
}
}