Skip to content

Commit

Permalink
Explicit string (de)serialize for optional serde-with-str values (#565)
Browse files Browse the repository at this point in the history
  • Loading branch information
paupino committed Jan 13, 2023
1 parent 69c1e7f commit 2da7a0d
Showing 1 changed file with 58 additions and 3 deletions.
61 changes: 58 additions & 3 deletions src/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ pub mod str_option {
where
D: serde::de::Deserializer<'de>,
{
deserializer.deserialize_option(OptionDecimalVisitor)
deserializer.deserialize_option(OptionDecimalStrVisitor)
}

pub fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
Expand All @@ -269,7 +269,7 @@ pub mod str_option {
match *value {
Some(ref decimal) => {
let decimal = crate::str::to_str_internal(decimal, true, None);
serializer.serialize_str(decimal.0.as_ref())
serializer.serialize_some(decimal.0.as_ref())
}
None => serializer.serialize_none(),
}
Expand Down Expand Up @@ -404,6 +404,35 @@ impl<'de> serde::de::Visitor<'de> for OptionDecimalVisitor {
}
}

#[cfg(feature = "serde-with-str")]
struct OptionDecimalStrVisitor;

#[cfg(feature = "serde-with-str")]
impl<'de> serde::de::Visitor<'de> for OptionDecimalStrVisitor {
type Value = Option<Decimal>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
println!("Here4");
formatter.write_str("a Decimal type representing a fixed-point number")
}

fn visit_none<E>(self) -> Result<Option<Decimal>, E>
where
E: serde::de::Error,
{
println!("Here2");
Ok(None)
}

fn visit_some<D>(self, d: D) -> Result<Option<Decimal>, D::Error>
where
D: serde::de::Deserializer<'de>,
{
println!("Here3");
d.deserialize_str(DecimalVisitor).map(Some)
}
}

#[cfg(feature = "serde-with-arbitrary-precision")]
struct DecimalKey;

Expand Down Expand Up @@ -744,14 +773,15 @@ mod test {
use bincode::{deserialize, serialize};

#[derive(Serialize, Deserialize)]
pub struct BincodeExample {
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"),
Expand All @@ -768,6 +798,31 @@ mod test {
}
}

#[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<Decimal>,
}

// 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() {
Expand Down

0 comments on commit 2da7a0d

Please sign in to comment.