Skip to main content

icydb_schema/decimal/
wire.rs

1use crate::{TypeParseError, decimal::Decimal};
2
3use serde::{Deserialize, Serialize};
4
5impl<'de> Deserialize<'de> for Decimal {
6    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
7    where
8        D: serde::Deserializer<'de>,
9    {
10        // Wire and Serde both emit text, including non-human-readable formats.
11        let text = String::deserialize(deserializer)?;
12        text.parse::<Self>()
13            .map_err(|_| serde::de::Error::custom(TypeParseError::InvalidDecimal))
14    }
15}
16
17impl Serialize for Decimal {
18    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
19    where
20        S: serde::Serializer,
21    {
22        serializer.serialize_str(&self.to_string())
23    }
24}
25
26// lossy f32 done on purpose as these ORM floats aren't designed for NaN etc.
27impl From<f32> for Decimal {
28    fn from(n: f32) -> Self {
29        Self::from_f32_lossy(n).unwrap_or(Self::ZERO)
30    }
31}
32
33impl From<f64> for Decimal {
34    fn from(n: f64) -> Self {
35        Self::from_f64_lossy(n).unwrap_or(Self::ZERO)
36    }
37}
38
39macro_rules! impl_decimal_from_signed_int {
40    ( $( $type:ty ),* ) => {
41        $(
42            impl From<$type> for Decimal {
43                fn from(n: $type) -> Self {
44                    Self {
45                        mantissa: i128::from(n),
46                        scale: 0,
47                    }
48                }
49            }
50        )*
51    };
52}
53
54macro_rules! impl_decimal_from_unsigned_int {
55    ( $( $type:ty ),* ) => {
56        $(
57            impl From<$type> for Decimal {
58                fn from(n: $type) -> Self {
59                    Self {
60                        mantissa: i128::from(n),
61                        scale: 0,
62                    }
63                }
64            }
65        )*
66    };
67}
68
69impl_decimal_from_unsigned_int!(u8, u16, u32, u64);
70impl_decimal_from_signed_int!(i8, i16, i32, i64, i128);
71
72impl From<u128> for Decimal {
73    fn from(n: u128) -> Self {
74        let mantissa = i128::try_from(n).unwrap_or(i128::MAX);
75        Self { mantissa, scale: 0 }
76    }
77}