serde_smile/value/
big_decimal.rs1use crate::value::BigInteger;
2use serde::de::{self, MapAccess, Visitor};
3use serde::ser::SerializeStruct;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use serde_bytes::{ByteBuf, Bytes};
6use std::fmt;
7
8#[derive(Clone, PartialEq, Eq, Debug)]
17pub struct BigDecimal {
18 value: BigInteger,
19 scale: i32,
20}
21
22impl BigDecimal {
23 pub(crate) const STRUCT_NAME: &'static str = "\0SmileBigDecimal";
24 pub(crate) const SCALE_FIELD_NAME: &'static str = "\0SmileBigDecimalScale";
25 pub(crate) const VALUE_FIELD_NAME: &'static str = "\0SmileBigDecimalValue";
26
27 #[inline]
31 pub fn new(value: BigInteger, scale: i32) -> Self {
32 BigDecimal { scale, value }
33 }
34
35 #[inline]
37 pub fn unscaled_value(&self) -> &BigInteger {
38 &self.value
39 }
40
41 #[inline]
43 pub fn into_unscaled_value(self) -> BigInteger {
44 self.value
45 }
46
47 #[inline]
49 pub fn scale(&self) -> i32 {
50 self.scale
51 }
52}
53
54impl Serialize for BigDecimal {
55 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
56 where
57 S: Serializer,
58 {
59 let mut s = serializer.serialize_struct(Self::STRUCT_NAME, 2)?;
60 s.serialize_field(Self::SCALE_FIELD_NAME, &self.scale)?;
61 s.serialize_field(
62 Self::VALUE_FIELD_NAME,
63 &Bytes::new(self.value.as_be_bytes()),
64 )?;
65 s.end()
66 }
67}
68
69impl<'de> Deserialize<'de> for BigDecimal {
70 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
71 where
72 D: Deserializer<'de>,
73 {
74 deserializer.deserialize_struct(
75 Self::STRUCT_NAME,
76 &[Self::SCALE_FIELD_NAME, Self::VALUE_FIELD_NAME],
77 BigDecimalVisitor,
78 )
79 }
80}
81
82pub(crate) struct BigDecimalVisitor;
83
84impl BigDecimalVisitor {
85 pub(crate) fn finish_map<'de, A>(self, mut map: A) -> Result<BigDecimal, A::Error>
86 where
87 A: MapAccess<'de>,
88 {
89 let scale = map.next_value()?;
90
91 match map.next_key::<BigDecimalKey>()? {
92 Some(BigDecimalKey::Value) => {}
93 Some(_) | None => return Err(de::Error::custom("expected big decimal value field")),
94 }
95 let value = map
96 .next_value::<ByteBuf>()
97 .map(|b| BigInteger::from_be_bytes(b.into_vec()))?;
98
99 Ok(BigDecimal { scale, value })
100 }
101}
102
103impl<'de> Visitor<'de> for BigDecimalVisitor {
104 type Value = BigDecimal;
105
106 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
107 formatter.write_str("a big decimal")
108 }
109
110 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
111 where
112 A: MapAccess<'de>,
113 {
114 match map.next_key::<BigDecimalKey>()? {
115 Some(BigDecimalKey::Scale) => {}
116 Some(_) | None => return Err(de::Error::custom("expected big decimal scale field")),
117 }
118 self.finish_map(map)
119 }
120}
121
122enum BigDecimalKey {
123 Scale,
124 Value,
125}
126
127impl<'de> Deserialize<'de> for BigDecimalKey {
128 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
129 where
130 D: Deserializer<'de>,
131 {
132 struct KeyVisitor;
133
134 impl<'de> Visitor<'de> for KeyVisitor {
135 type Value = BigDecimalKey;
136
137 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
138 formatter.write_str("a valid big decimal field")
139 }
140
141 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
142 where
143 E: de::Error,
144 {
145 if v == BigDecimal::SCALE_FIELD_NAME {
146 Ok(BigDecimalKey::Scale)
147 } else if v == BigDecimal::VALUE_FIELD_NAME {
148 Ok(BigDecimalKey::Value)
149 } else {
150 Err(de::Error::custom("expected field with custom name"))
151 }
152 }
153 }
154
155 deserializer.deserialize_identifier(KeyVisitor)
156 }
157}