use crate::Decimal; use alloc::string::ToString; use core::{fmt, str::FromStr}; use num_traits::FromPrimitive; use serde::{self, de::Unexpected}; /// Serialize/deserialize Decimals as arbitrary precision numbers in JSON using the `arbitrary_precision` feature within `serde_json`. /// /// ``` /// # use serde::{Serialize, Deserialize}; /// # use rust_decimal::Decimal; /// # use std::str::FromStr; /// /// #[derive(Serialize, Deserialize)] /// pub struct ArbitraryExample { /// #[serde(with = "rust_decimal::serde::arbitrary_precision")] /// value: Decimal, /// } /// /// let value = ArbitraryExample { value: Decimal::from_str("123.400").unwrap() }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":123.400}"# /// ); /// ``` #[cfg(feature = "serde-with-arbitrary-precision")] pub mod arbitrary_precision { use super::*; use serde::Serialize; pub fn deserialize<'de, D>(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { deserializer.deserialize_any(DecimalVisitor) } pub fn serialize(value: &Decimal, serializer: S) -> Result where S: serde::Serializer, { serde_json::Number::from_str(&value.to_string()) .map_err(serde::ser::Error::custom)? .serialize(serializer) } } /// Serialize/deserialize optional Decimals as arbitrary precision numbers in JSON using the `arbitrary_precision` feature within `serde_json`. /// /// ``` /// # use serde::{Serialize, Deserialize}; /// # use rust_decimal::Decimal; /// # use std::str::FromStr; /// /// #[derive(Serialize, Deserialize)] /// pub struct ArbitraryExample { /// #[serde(with = "rust_decimal::serde::arbitrary_precision_option")] /// value: Option, /// } /// /// let value = ArbitraryExample { value: Some(Decimal::from_str("123.400").unwrap()) }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":123.400}"# /// ); /// /// let value = ArbitraryExample { value: None }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":null}"# /// ); /// ``` #[cfg(feature = "serde-with-arbitrary-precision")] pub mod arbitrary_precision_option { use super::*; use serde::Serialize; pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::de::Deserializer<'de>, { deserializer.deserialize_option(OptionDecimalVisitor) } pub fn serialize(value: &Option, serializer: S) -> Result where S: serde::Serializer, { match *value { Some(ref decimal) => serde_json::Number::from_str(&decimal.to_string()) .map_err(serde::ser::Error::custom)? .serialize(serializer), None => serializer.serialize_none(), } } } /// Serialize/deserialize Decimals as floats. /// /// ``` /// # use serde::{Serialize, Deserialize}; /// # use rust_decimal::Decimal; /// # use std::str::FromStr; /// /// #[derive(Serialize, Deserialize)] /// pub struct FloatExample { /// #[serde(with = "rust_decimal::serde::float")] /// value: Decimal, /// } /// /// let value = FloatExample { value: Decimal::from_str("123.400").unwrap() }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":123.4}"# /// ); /// ``` #[cfg(feature = "serde-with-float")] pub mod float { use super::*; use serde::Serialize; pub fn deserialize<'de, D>(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { deserializer.deserialize_any(DecimalVisitor) } pub fn serialize(value: &Decimal, serializer: S) -> Result where S: serde::Serializer, { use num_traits::ToPrimitive; value.to_f64().unwrap().serialize(serializer) } } /// Serialize/deserialize optional Decimals as floats. /// /// ``` /// # use serde::{Serialize, Deserialize}; /// # use rust_decimal::Decimal; /// # use std::str::FromStr; /// /// #[derive(Serialize, Deserialize)] /// pub struct FloatExample { /// #[serde(with = "rust_decimal::serde::float_option")] /// value: Option, /// } /// /// let value = FloatExample { value: Some(Decimal::from_str("123.400").unwrap()) }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":123.4}"# /// ); /// /// let value = FloatExample { value: None }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":null}"# /// ); /// ``` #[cfg(feature = "serde-with-float")] pub mod float_option { use super::*; use serde::Serialize; pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::de::Deserializer<'de>, { deserializer.deserialize_option(OptionDecimalVisitor) } pub fn serialize(value: &Option, serializer: S) -> Result where S: serde::Serializer, { match *value { Some(ref decimal) => { use num_traits::ToPrimitive; decimal.to_f64().unwrap().serialize(serializer) } None => serializer.serialize_none(), } } } /// Serialize/deserialize Decimals as strings. This is particularly useful when using binary encoding formats. /// /// ``` /// # use serde::{Serialize, Deserialize}; /// # use rust_decimal::Decimal; /// # use std::str::FromStr; /// /// #[derive(Serialize, Deserialize)] /// pub struct StringExample { /// #[serde(with = "rust_decimal::serde::str")] /// value: Decimal, /// } /// /// let value = StringExample { value: Decimal::from_str("123.400").unwrap() }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":"123.400"}"# /// ); /// /// ``` #[cfg(feature = "serde-with-str")] pub mod str { use super::*; pub fn deserialize<'de, D>(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { deserializer.deserialize_str(DecimalVisitor) } pub fn serialize(value: &Decimal, serializer: S) -> Result where S: serde::Serializer, { let value = crate::str::to_str_internal(value, true, None); serializer.serialize_str(value.0.as_ref()) } } /// Serialize/deserialize optional Decimals as strings. This is particularly useful when using binary encoding formats. /// /// ``` /// # use serde::{Serialize, Deserialize}; /// # use rust_decimal::Decimal; /// # use std::str::FromStr; /// /// #[derive(Serialize, Deserialize)] /// pub struct StringExample { /// #[serde(with = "rust_decimal::serde::str_option")] /// value: Option, /// } /// /// let value = StringExample { value: Some(Decimal::from_str("123.400").unwrap()) }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":"123.400"}"# /// ); /// /// let value = StringExample { value: None }; /// assert_eq!( /// &serde_json::to_string(&value).unwrap(), /// r#"{"value":null}"# /// ); /// ``` #[cfg(feature = "serde-with-str")] pub mod str_option { use super::*; pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::de::Deserializer<'de>, { deserializer.deserialize_option(OptionDecimalStrVisitor) } pub fn serialize(value: &Option, serializer: S) -> Result where S: serde::Serializer, { match *value { Some(ref decimal) => { let decimal = crate::str::to_str_internal(decimal, true, None); serializer.serialize_some(decimal.0.as_ref()) } None => serializer.serialize_none(), } } } #[cfg(not(feature = "serde-str"))] impl<'de> serde::Deserialize<'de> for Decimal { fn deserialize(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { deserializer.deserialize_any(DecimalVisitor) } } #[cfg(all(feature = "serde-str", not(feature = "serde-float")))] impl<'de> serde::Deserialize<'de> for Decimal { fn deserialize(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { deserializer.deserialize_str(DecimalVisitor) } } #[cfg(all(feature = "serde-str", feature = "serde-float"))] impl<'de> serde::Deserialize<'de> for Decimal { fn deserialize(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { deserializer.deserialize_f64(DecimalVisitor) } } // It's a shame this needs to be redefined for this feature and not able to be referenced directly #[cfg(feature = "serde-with-arbitrary-precision")] const DECIMAL_KEY_TOKEN: &str = "$serde_json::private::Number"; struct DecimalVisitor; impl<'de> serde::de::Visitor<'de> for DecimalVisitor { type Value = Decimal; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "a Decimal type representing a fixed-point number") } fn visit_i64(self, value: i64) -> Result where E: serde::de::Error, { match Decimal::from_i64(value) { Some(s) => Ok(s), None => Err(E::invalid_value(Unexpected::Signed(value), &self)), } } fn visit_u64(self, value: u64) -> Result where E: serde::de::Error, { match Decimal::from_u64(value) { Some(s) => Ok(s), None => Err(E::invalid_value(Unexpected::Unsigned(value), &self)), } } fn visit_f64(self, value: f64) -> Result where E: serde::de::Error, { Decimal::from_str(&value.to_string()).map_err(|_| E::invalid_value(Unexpected::Float(value), &self)) } fn visit_str(self, value: &str) -> Result where E: serde::de::Error, { Decimal::from_str(value) .or_else(|_| Decimal::from_scientific(value)) .map_err(|_| E::invalid_value(Unexpected::Str(value), &self)) } #[cfg(feature = "serde-with-arbitrary-precision")] fn visit_map(self, map: A) -> Result where A: serde::de::MapAccess<'de>, { let mut map = map; let value = map.next_key::()?; if value.is_none() { return Err(serde::de::Error::invalid_type(Unexpected::Map, &self)); } let v: DecimalFromString = map.next_value()?; Ok(v.value) } } struct OptionDecimalVisitor; impl<'de> serde::de::Visitor<'de> for OptionDecimalVisitor { type Value = Option; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a Decimal type representing a fixed-point number") } fn visit_none(self) -> Result, E> where E: serde::de::Error, { Ok(None) } #[cfg(all(feature = "serde-str", feature = "serde-float"))] fn visit_some(self, d: D) -> Result, D::Error> where D: serde::de::Deserializer<'de>, { // We've got multiple types that we may see so we need to use any d.deserialize_any(DecimalVisitor).map(Some) } #[cfg(not(all(feature = "serde-str", feature = "serde-float")))] fn visit_some(self, d: D) -> Result, D::Error> where D: serde::de::Deserializer<'de>, { ::deserialize(d).map(Some) } } #[cfg(feature = "serde-with-str")] struct OptionDecimalStrVisitor; #[cfg(feature = "serde-with-str")] impl<'de> serde::de::Visitor<'de> for OptionDecimalStrVisitor { type Value = Option; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a Decimal type representing a fixed-point number") } fn visit_none(self) -> Result, E> where E: serde::de::Error, { Ok(None) } fn visit_some(self, d: D) -> Result, D::Error> where D: serde::de::Deserializer<'de>, { d.deserialize_str(DecimalVisitor).map(Some) } } #[cfg(feature = "serde-with-arbitrary-precision")] struct DecimalKey; #[cfg(feature = "serde-with-arbitrary-precision")] impl<'de> serde::de::Deserialize<'de> for DecimalKey { fn deserialize(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { struct FieldVisitor; impl<'de> serde::de::Visitor<'de> for FieldVisitor { type Value = (); fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a valid decimal field") } fn visit_str(self, s: &str) -> Result<(), E> where E: serde::de::Error, { if s == DECIMAL_KEY_TOKEN { Ok(()) } else { Err(serde::de::Error::custom("expected field with custom name")) } } } deserializer.deserialize_identifier(FieldVisitor)?; Ok(DecimalKey) } } #[cfg(feature = "serde-with-arbitrary-precision")] pub struct DecimalFromString { pub value: Decimal, } #[cfg(feature = "serde-with-arbitrary-precision")] impl<'de> serde::de::Deserialize<'de> for DecimalFromString { fn deserialize(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { struct Visitor; impl<'de> serde::de::Visitor<'de> for Visitor { type Value = DecimalFromString; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("string containing a decimal") } fn visit_str(self, value: &str) -> Result where E: serde::de::Error, { let d = Decimal::from_str(value) .or_else(|_| Decimal::from_scientific(value)) .map_err(serde::de::Error::custom)?; Ok(DecimalFromString { value: d }) } } deserializer.deserialize_str(Visitor) } } #[cfg(not(feature = "serde-float"))] impl serde::Serialize for Decimal { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let value = crate::str::to_str_internal(self, true, None); serializer.serialize_str(value.0.as_ref()) } } #[cfg(all(feature = "serde-float", not(feature = "serde-arbitrary-precision")))] impl serde::Serialize for Decimal { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { use num_traits::ToPrimitive; serializer.serialize_f64(self.to_f64().unwrap()) } } #[cfg(all(feature = "serde-float", feature = "serde-arbitrary-precision"))] impl serde::Serialize for Decimal { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { serde_json::Number::from_str(&self.to_string()) .map_err(serde::ser::Error::custom)? .serialize(serializer) } } #[cfg(test)] mod test { use super::*; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] struct Record { amount: Decimal, } #[test] #[cfg(not(feature = "serde-str"))] fn deserialize_valid_decimal() { let data = [ ("{\"amount\":\"1.234\"}", "1.234"), ("{\"amount\":1234}", "1234"), ("{\"amount\":1234.56}", "1234.56"), ("{\"amount\":\"1.23456e3\"}", "1234.56"), ]; for &(serialized, value) in data.iter() { let result = serde_json::from_str(serialized); assert_eq!( true, result.is_ok(), "expected successful deserialization for {}. Error: {:?}", serialized, result.err().unwrap() ); let record: Record = result.unwrap(); assert_eq!( value, record.amount.to_string(), "expected: {}, actual: {}", value, record.amount.to_string() ); } } #[test] #[cfg(feature = "serde-arbitrary-precision")] fn deserialize_basic_decimal() { let d: Decimal = serde_json::from_str("1.1234127836128763").unwrap(); // Typically, this would not work without this feature enabled due to rounding assert_eq!(d.to_string(), "1.1234127836128763"); } #[test] #[should_panic] fn deserialize_invalid_decimal() { let serialized = "{\"amount\":\"foo\"}"; let _: Record = serde_json::from_str(serialized).unwrap(); } #[test] #[cfg(not(feature = "serde-float"))] fn serialize_decimal() { let record = Record { amount: Decimal::new(1234, 3), }; let serialized = serde_json::to_string(&record).unwrap(); assert_eq!("{\"amount\":\"1.234\"}", serialized); } #[test] #[cfg(not(feature = "serde-float"))] fn serialize_negative_zero() { let record = Record { amount: -Decimal::ZERO }; let serialized = serde_json::to_string(&record).unwrap(); assert_eq!("{\"amount\":\"-0\"}", serialized); } #[test] #[cfg(feature = "serde-float")] fn serialize_decimal() { let record = Record { amount: Decimal::new(1234, 3), }; let serialized = serde_json::to_string(&record).unwrap(); assert_eq!("{\"amount\":1.234}", serialized); } #[test] #[cfg(all(feature = "serde-float", feature = "serde-arbitrary-precision"))] fn serialize_decimal_roundtrip() { let record = Record { // 4.81 is intentionally chosen as it is unrepresentable as a floating point number, meaning this test // would fail if the `serde-arbitrary-precision` was not activated. amount: Decimal::new(481, 2), }; let serialized = serde_json::to_string(&record).unwrap(); assert_eq!("{\"amount\":4.81}", serialized); let deserialized: Record = serde_json::from_str(&serialized).unwrap(); assert_eq!(record.amount, deserialized.amount); } #[test] #[cfg(all(feature = "serde-str", not(feature = "serde-float")))] fn serialize_decimal_roundtrip() { let record = Record { amount: Decimal::new(481, 2), }; let serialized = serde_json::to_string(&record).unwrap(); assert_eq!("{\"amount\":\"4.81\"}", serialized); let deserialized: Record = serde_json::from_str(&serialized).unwrap(); assert_eq!(record.amount, deserialized.amount); } #[test] #[cfg(all(feature = "serde-str", not(feature = "serde-float")))] fn bincode_serialization() { use bincode::{deserialize, serialize}; let data = [ "0", "0.00", "3.14159", "-3.14159", "1234567890123.4567890", "-1234567890123.4567890", "5233.9008808150288439427720175", "-5233.9008808150288439427720175", ]; for &raw in data.iter() { let value = Decimal::from_str(raw).unwrap(); let encoded = serialize(&value).unwrap(); let decoded: Decimal = deserialize(&encoded[..]).unwrap(); assert_eq!(value, decoded); assert_eq!(8usize + raw.len(), encoded.len()); } } #[test] #[cfg(all(feature = "serde-str", feature = "serde-float"))] fn bincode_serialization() { use bincode::{deserialize, serialize}; let data = [ ("0", "0"), ("0.00", "0.00"), ("3.14159", "3.14159"), ("-3.14159", "-3.14159"), ("1234567890123.4567890", "1234567890123.4568"), ("-1234567890123.4567890", "-1234567890123.4568"), ]; for &(value, expected) in data.iter() { let value = Decimal::from_str(value).unwrap(); let expected = Decimal::from_str(expected).unwrap(); let encoded = serialize(&value).unwrap(); let decoded: Decimal = deserialize(&encoded[..]).unwrap(); assert_eq!(expected, decoded); assert_eq!(8usize, encoded.len()); } } #[test] #[cfg(all(feature = "serde-str", not(feature = "serde-float")))] fn bincode_nested_serialization() { // Issue #361 #[derive(Deserialize, Serialize, Debug)] pub struct Foo { value: Decimal, } let s = Foo { value: Decimal::new(-1, 3).round_dp(0), }; let ser = bincode::serialize(&s).unwrap(); let des: Foo = bincode::deserialize(&ser).unwrap(); assert_eq!(des.value, s.value); } #[test] #[cfg(feature = "serde-with-arbitrary-precision")] fn with_arbitrary_precision() { #[derive(Serialize, Deserialize)] pub struct ArbitraryExample { #[serde(with = "crate::serde::arbitrary_precision")] value: Decimal, } let value = ArbitraryExample { value: Decimal::from_str("123.400").unwrap(), }; assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":123.400}"#); } #[test] #[cfg(feature = "serde-with-arbitrary-precision")] fn with_arbitrary_precision_from_string() { #[derive(Serialize, Deserialize)] pub struct ArbitraryExample { #[serde(with = "crate::serde::arbitrary_precision")] value: Decimal, } let value: ArbitraryExample = serde_json::from_str(r#"{"value":"1.1234127836128763"}"#).unwrap(); assert_eq!(value.value.to_string(), "1.1234127836128763"); } #[test] #[cfg(feature = "serde-with-float")] fn with_float() { #[derive(Serialize, Deserialize)] pub struct FloatExample { #[serde(with = "crate::serde::float")] value: Decimal, } let value = FloatExample { value: Decimal::from_str("123.400").unwrap(), }; assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":123.4}"#); } #[test] #[cfg(feature = "serde-with-str")] fn with_str() { #[derive(Serialize, Deserialize)] pub struct StringExample { #[serde(with = "crate::serde::str")] value: Decimal, } let value = StringExample { value: Decimal::from_str("123.400").unwrap(), }; assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":"123.400"}"#); } #[test] #[cfg(feature = "serde-with-str")] fn with_str_bincode() { use bincode::{deserialize, serialize}; #[derive(Serialize, Deserialize)] struct BincodeExample { #[serde(with = "crate::serde::str")] value: Decimal, } let data = [ ("0", "0"), ("0.00", "0.00"), ("1.234", "1.234"), ("3.14159", "3.14159"), ("-3.14159", "-3.14159"), ("1234567890123.4567890", "1234567890123.4567890"), ("-1234567890123.4567890", "-1234567890123.4567890"), ]; for &(value, expected) in data.iter() { let value = Decimal::from_str(value).unwrap(); let expected = Decimal::from_str(expected).unwrap(); let input = BincodeExample { value }; let encoded = serialize(&input).unwrap(); let decoded: BincodeExample = deserialize(&encoded[..]).unwrap(); assert_eq!(expected, decoded.value); } } #[test] #[cfg(feature = "serde-with-str")] fn with_str_bincode_optional() { use bincode::{deserialize, serialize}; #[derive(Serialize, Deserialize)] struct BincodeExample { #[serde(with = "crate::serde::str_option")] value: Option, } // Some(value) let value = Some(Decimal::new(1234, 3)); let input = BincodeExample { value }; let encoded = serialize(&input).unwrap(); let decoded: BincodeExample = deserialize(&encoded[..]).unwrap(); assert_eq!(value, decoded.value, "Some(value)"); // None let input = BincodeExample { value: None }; let encoded = serialize(&input).unwrap(); let decoded: BincodeExample = deserialize(&encoded[..]).unwrap(); assert_eq!(None, decoded.value, "None"); } #[test] #[cfg(feature = "serde-with-str")] fn with_str_optional() { #[derive(Serialize, Deserialize)] pub struct StringExample { #[serde(with = "crate::serde::str_option")] value: Option, } let original = StringExample { value: Some(Decimal::from_str("123.400").unwrap()), }; assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":"123.400"}"#); let deserialized: StringExample = serde_json::from_str(r#"{"value":"123.400"}"#).unwrap(); assert_eq!(deserialized.value, original.value); assert!(deserialized.value.is_some()); assert_eq!(deserialized.value.unwrap().unpack(), original.value.unwrap().unpack()); // Null tests let original = StringExample { value: None }; assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#); let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap(); assert_eq!(deserialized.value, original.value); assert!(deserialized.value.is_none()); } #[test] #[cfg(feature = "serde-with-float")] fn with_float_optional() { #[derive(Serialize, Deserialize)] pub struct StringExample { #[serde(with = "crate::serde::float_option")] value: Option, } let original = StringExample { value: Some(Decimal::from_str("123.400").unwrap()), }; assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":123.4}"#); let deserialized: StringExample = serde_json::from_str(r#"{"value":123.4}"#).unwrap(); assert_eq!(deserialized.value, original.value); assert!(deserialized.value.is_some()); // Scale is different! // Null tests let original = StringExample { value: None }; assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#); let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap(); assert_eq!(deserialized.value, original.value); assert!(deserialized.value.is_none()); } #[test] #[cfg(feature = "serde-with-arbitrary-precision")] fn with_arbitrary_precision_optional() { #[derive(Serialize, Deserialize)] pub struct StringExample { #[serde(with = "crate::serde::arbitrary_precision_option")] value: Option, } let original = StringExample { value: Some(Decimal::from_str("123.400").unwrap()), }; assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":123.400}"#); let deserialized: StringExample = serde_json::from_str(r#"{"value":123.400}"#).unwrap(); assert_eq!(deserialized.value, original.value); assert!(deserialized.value.is_some()); assert_eq!(deserialized.value.unwrap().unpack(), original.value.unwrap().unpack()); // Null tests let original = StringExample { value: None }; assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#); let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap(); assert_eq!(deserialized.value, original.value); assert!(deserialized.value.is_none()); } }