1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
pub use options_common::{Decimal, ExpirationDate, OptionType}; use num_rational::Rational64; use serde::{de, Deserialize, Deserializer, Serializer}; use std::convert::TryInto; use std::fmt::{self, Display}; use std::str::FromStr; pub mod string_serialize { use super::*; pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error> where T: Display, S: Serializer, { serializer.collect_str(value) } pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error> where T: FromStr, T::Err: Display, D: Deserializer<'de>, { String::deserialize(deserializer)? .parse() .map_err(de::Error::custom) } } pub mod optional_string_serialize { use super::*; pub fn serialize<T, S>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error> where T: Display, S: Serializer, { match value { Some(value) => serializer.serialize_some(&value.to_string()), None => serializer.serialize_none(), } } pub fn deserialize<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error> where T: FromStr, T::Err: Display, D: Deserializer<'de>, { let string: Option<String> = Option::deserialize(deserializer)?; string .map(|s| s.parse().map_err(de::Error::custom)) .transpose() } } pub fn deserialize_integer_or_string_as_decimal<'de, D>( deserializer: D, ) -> Result<Decimal, D::Error> where D: Deserializer<'de>, { deserializer.deserialize_any(DeserializeIntegerOrStringAsDecimal) } struct DeserializeIntegerOrStringAsDecimal; impl<'de> de::Visitor<'de> for DeserializeIntegerOrStringAsDecimal { type Value = Decimal; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("an integer or a string") } fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> where E: de::Error, { Ok(Decimal(Rational64::from_integer(v))) } fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> where E: de::Error, { self.visit_i64(v.try_into().map_err(de::Error::custom)?) } fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: de::Error, { Decimal::from_str(v).map_err(de::Error::custom) } }