rust_decimal/
serde.rs

1use crate::Decimal;
2use alloc::string::ToString;
3use core::{fmt, str::FromStr};
4use num_traits::FromPrimitive;
5use serde::{self, de::Unexpected};
6
7/// Serialize/deserialize Decimals as arbitrary precision numbers in JSON using the `arbitrary_precision` feature within `serde_json`.
8///
9/// ```
10/// # use serde::{Serialize, Deserialize};
11/// # use rust_decimal::Decimal;
12/// # use std::str::FromStr;
13///
14/// #[derive(Serialize, Deserialize)]
15/// pub struct ArbitraryExample {
16///     #[serde(with = "rust_decimal::serde::arbitrary_precision")]
17///     value: Decimal,
18/// }
19///
20/// let value = ArbitraryExample { value: Decimal::from_str("123.400").unwrap() };
21/// assert_eq!(
22///     &serde_json::to_string(&value).unwrap(),
23///     r#"{"value":123.400}"#
24/// );
25/// ```
26#[cfg(feature = "serde-with-arbitrary-precision")]
27pub mod arbitrary_precision {
28    use super::*;
29    use serde::Serialize;
30
31    pub fn deserialize<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
32    where
33        D: serde::de::Deserializer<'de>,
34    {
35        deserializer.deserialize_any(DecimalVisitor)
36    }
37
38    pub fn serialize<S>(value: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
39    where
40        S: serde::Serializer,
41    {
42        serde_json::Number::from_str(&value.to_string())
43            .map_err(serde::ser::Error::custom)?
44            .serialize(serializer)
45    }
46}
47
48/// Serialize/deserialize optional Decimals as arbitrary precision numbers in JSON using the `arbitrary_precision` feature within `serde_json`.
49///
50/// ```
51/// # use serde::{Serialize, Deserialize};
52/// # use rust_decimal::Decimal;
53/// # use std::str::FromStr;
54///
55/// #[derive(Serialize, Deserialize)]
56/// pub struct ArbitraryExample {
57///     #[serde(with = "rust_decimal::serde::arbitrary_precision_option")]
58///     value: Option<Decimal>,
59/// }
60///
61/// let value = ArbitraryExample { value: Some(Decimal::from_str("123.400").unwrap()) };
62/// assert_eq!(
63///     &serde_json::to_string(&value).unwrap(),
64///     r#"{"value":123.400}"#
65/// );
66///
67/// let value = ArbitraryExample { value: None };
68/// assert_eq!(
69///     &serde_json::to_string(&value).unwrap(),
70///     r#"{"value":null}"#
71/// );
72/// ```
73#[cfg(feature = "serde-with-arbitrary-precision")]
74pub mod arbitrary_precision_option {
75    use super::*;
76    use serde::Serialize;
77
78    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
79    where
80        D: serde::de::Deserializer<'de>,
81    {
82        deserializer.deserialize_option(OptionDecimalVisitor)
83    }
84
85    pub fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
86    where
87        S: serde::Serializer,
88    {
89        match *value {
90            Some(ref decimal) => serde_json::Number::from_str(&decimal.to_string())
91                .map_err(serde::ser::Error::custom)?
92                .serialize(serializer),
93            None => serializer.serialize_none(),
94        }
95    }
96}
97
98/// Serialize/deserialize Decimals as floats.
99///
100/// ```
101/// # use serde::{Serialize, Deserialize};
102/// # use rust_decimal::Decimal;
103/// # use std::str::FromStr;
104///
105/// #[derive(Serialize, Deserialize)]
106/// pub struct FloatExample {
107///     #[serde(with = "rust_decimal::serde::float")]
108///     value: Decimal,
109/// }
110///
111/// let value = FloatExample { value: Decimal::from_str("123.400").unwrap() };
112/// assert_eq!(
113///     &serde_json::to_string(&value).unwrap(),
114///     r#"{"value":123.4}"#
115/// );
116/// ```
117#[cfg(feature = "serde-with-float")]
118pub mod float {
119    use super::*;
120    use serde::Serialize;
121
122    pub fn deserialize<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
123    where
124        D: serde::de::Deserializer<'de>,
125    {
126        deserializer.deserialize_any(DecimalVisitor)
127    }
128
129    pub fn serialize<S>(value: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
130    where
131        S: serde::Serializer,
132    {
133        use num_traits::ToPrimitive;
134        value.to_f64().unwrap().serialize(serializer)
135    }
136}
137
138/// Serialize/deserialize optional Decimals as floats.
139///
140/// ```
141/// # use serde::{Serialize, Deserialize};
142/// # use rust_decimal::Decimal;
143/// # use std::str::FromStr;
144///
145/// #[derive(Serialize, Deserialize)]
146/// pub struct FloatExample {
147///     #[serde(with = "rust_decimal::serde::float_option")]
148///     value: Option<Decimal>,
149/// }
150///
151/// let value = FloatExample { value: Some(Decimal::from_str("123.400").unwrap()) };
152/// assert_eq!(
153///     &serde_json::to_string(&value).unwrap(),
154///     r#"{"value":123.4}"#
155/// );
156///
157/// let value = FloatExample { value: None };
158/// assert_eq!(
159///     &serde_json::to_string(&value).unwrap(),
160///     r#"{"value":null}"#
161/// );
162/// ```
163#[cfg(feature = "serde-with-float")]
164pub mod float_option {
165    use super::*;
166    use serde::Serialize;
167
168    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
169    where
170        D: serde::de::Deserializer<'de>,
171    {
172        deserializer.deserialize_option(OptionDecimalVisitor)
173    }
174
175    pub fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
176    where
177        S: serde::Serializer,
178    {
179        match *value {
180            Some(ref decimal) => {
181                use num_traits::ToPrimitive;
182                decimal.to_f64().unwrap().serialize(serializer)
183            }
184            None => serializer.serialize_none(),
185        }
186    }
187}
188
189/// Serialize/deserialize Decimals as strings. This is particularly useful when using binary encoding formats.
190///
191/// ```
192/// # use serde::{Serialize, Deserialize};
193/// # use rust_decimal::Decimal;
194/// # use std::str::FromStr;
195///
196/// #[derive(Serialize, Deserialize)]
197/// pub struct StringExample {
198///     #[serde(with = "rust_decimal::serde::str")]
199///     value: Decimal,
200/// }
201///
202/// let value = StringExample { value: Decimal::from_str("123.400").unwrap() };
203/// assert_eq!(
204///     &serde_json::to_string(&value).unwrap(),
205///     r#"{"value":"123.400"}"#
206/// );
207///
208/// ```
209#[cfg(feature = "serde-with-str")]
210pub mod str {
211    use super::*;
212
213    pub fn deserialize<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
214    where
215        D: serde::de::Deserializer<'de>,
216    {
217        deserializer.deserialize_str(DecimalVisitor)
218    }
219
220    pub fn serialize<S>(value: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
221    where
222        S: serde::Serializer,
223    {
224        let value = crate::str::to_str_internal(value, true, None);
225        serializer.serialize_str(value.0.as_ref())
226    }
227}
228
229/// Serialize/deserialize optional Decimals as strings. This is particularly useful when using binary encoding formats.
230///
231/// ```
232/// # use serde::{Serialize, Deserialize};
233/// # use rust_decimal::Decimal;
234/// # use std::str::FromStr;
235///
236/// #[derive(Serialize, Deserialize)]
237/// pub struct StringExample {
238///     #[serde(with = "rust_decimal::serde::str_option")]
239///     value: Option<Decimal>,
240/// }
241///
242/// let value = StringExample { value: Some(Decimal::from_str("123.400").unwrap()) };
243/// assert_eq!(
244///     &serde_json::to_string(&value).unwrap(),
245///     r#"{"value":"123.400"}"#
246/// );
247///
248/// let value = StringExample { value: None };
249/// assert_eq!(
250///     &serde_json::to_string(&value).unwrap(),
251///     r#"{"value":null}"#
252/// );
253/// ```
254#[cfg(feature = "serde-with-str")]
255pub mod str_option {
256    use super::*;
257
258    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
259    where
260        D: serde::de::Deserializer<'de>,
261    {
262        deserializer.deserialize_option(OptionDecimalStrVisitor)
263    }
264
265    pub fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
266    where
267        S: serde::Serializer,
268    {
269        match *value {
270            Some(ref decimal) => {
271                let decimal = crate::str::to_str_internal(decimal, true, None);
272                serializer.serialize_some::<str>(decimal.0.as_ref())
273            }
274            None => serializer.serialize_none(),
275        }
276    }
277}
278
279#[cfg(not(feature = "serde-str"))]
280impl<'de> serde::Deserialize<'de> for Decimal {
281    fn deserialize<D>(deserializer: D) -> Result<Decimal, D::Error>
282    where
283        D: serde::de::Deserializer<'de>,
284    {
285        deserializer.deserialize_any(DecimalVisitor)
286    }
287}
288
289#[cfg(all(feature = "serde-str", not(feature = "serde-float")))]
290impl<'de> serde::Deserialize<'de> for Decimal {
291    fn deserialize<D>(deserializer: D) -> Result<Decimal, D::Error>
292    where
293        D: serde::de::Deserializer<'de>,
294    {
295        deserializer.deserialize_str(DecimalVisitor)
296    }
297}
298
299#[cfg(all(feature = "serde-str", feature = "serde-float"))]
300impl<'de> serde::Deserialize<'de> for Decimal {
301    fn deserialize<D>(deserializer: D) -> Result<Decimal, D::Error>
302    where
303        D: serde::de::Deserializer<'de>,
304    {
305        deserializer.deserialize_f64(DecimalVisitor)
306    }
307}
308
309// It's a shame this needs to be redefined for this feature and not able to be referenced directly
310#[cfg(feature = "serde-with-arbitrary-precision")]
311const DECIMAL_KEY_TOKEN: &str = "$serde_json::private::Number";
312
313struct DecimalVisitor;
314
315impl<'de> serde::de::Visitor<'de> for DecimalVisitor {
316    type Value = Decimal;
317
318    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
319        write!(formatter, "a Decimal type representing a fixed-point number")
320    }
321
322    fn visit_i64<E>(self, value: i64) -> Result<Decimal, E>
323    where
324        E: serde::de::Error,
325    {
326        match Decimal::from_i64(value) {
327            Some(s) => Ok(s),
328            None => Err(E::invalid_value(Unexpected::Signed(value), &self)),
329        }
330    }
331
332    fn visit_u64<E>(self, value: u64) -> Result<Decimal, E>
333    where
334        E: serde::de::Error,
335    {
336        match Decimal::from_u64(value) {
337            Some(s) => Ok(s),
338            None => Err(E::invalid_value(Unexpected::Unsigned(value), &self)),
339        }
340    }
341
342    fn visit_f64<E>(self, value: f64) -> Result<Decimal, E>
343    where
344        E: serde::de::Error,
345    {
346        Decimal::from_str(&value.to_string()).map_err(|_| E::invalid_value(Unexpected::Float(value), &self))
347    }
348
349    fn visit_str<E>(self, value: &str) -> Result<Decimal, E>
350    where
351        E: serde::de::Error,
352    {
353        Decimal::from_str(value)
354            .or_else(|_| Decimal::from_scientific(value))
355            .map_err(|_| E::invalid_value(Unexpected::Str(value), &self))
356    }
357
358    #[cfg(feature = "serde-with-arbitrary-precision")]
359    fn visit_map<A>(self, map: A) -> Result<Decimal, A::Error>
360    where
361        A: serde::de::MapAccess<'de>,
362    {
363        let mut map = map;
364        let value = map.next_key::<DecimalKey>()?;
365        if value.is_none() {
366            return Err(serde::de::Error::invalid_type(Unexpected::Map, &self));
367        }
368        let v: DecimalFromString = map.next_value()?;
369        Ok(v.value)
370    }
371}
372
373#[cfg(any(feature = "serde-with-float", feature = "serde-with-arbitrary-precision"))]
374struct OptionDecimalVisitor;
375
376#[cfg(any(feature = "serde-with-float", feature = "serde-with-arbitrary-precision"))]
377impl<'de> serde::de::Visitor<'de> for OptionDecimalVisitor {
378    type Value = Option<Decimal>;
379
380    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
381        formatter.write_str("a Decimal type representing a fixed-point number")
382    }
383
384    fn visit_none<E>(self) -> Result<Option<Decimal>, E>
385    where
386        E: serde::de::Error,
387    {
388        Ok(None)
389    }
390
391    #[cfg(all(feature = "serde-str", feature = "serde-float"))]
392    fn visit_some<D>(self, d: D) -> Result<Option<Decimal>, D::Error>
393    where
394        D: serde::de::Deserializer<'de>,
395    {
396        // We've got multiple types that we may see so we need to use any
397        d.deserialize_any(DecimalVisitor).map(Some)
398    }
399
400    #[cfg(not(all(feature = "serde-str", feature = "serde-float")))]
401    fn visit_some<D>(self, d: D) -> Result<Option<Decimal>, D::Error>
402    where
403        D: serde::de::Deserializer<'de>,
404    {
405        <Decimal as serde::Deserialize>::deserialize(d).map(Some)
406    }
407}
408
409#[cfg(feature = "serde-with-str")]
410struct OptionDecimalStrVisitor;
411
412#[cfg(feature = "serde-with-str")]
413impl<'de> serde::de::Visitor<'de> for OptionDecimalStrVisitor {
414    type Value = Option<Decimal>;
415
416    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
417        formatter.write_str("a Decimal type representing a fixed-point number")
418    }
419
420    fn visit_none<E>(self) -> Result<Option<Decimal>, E>
421    where
422        E: serde::de::Error,
423    {
424        Ok(None)
425    }
426
427    fn visit_some<D>(self, d: D) -> Result<Option<Decimal>, D::Error>
428    where
429        D: serde::de::Deserializer<'de>,
430    {
431        d.deserialize_str(Self)
432    }
433
434    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
435    where
436        E: serde::de::Error,
437    {
438        match v.is_empty() {
439            true => Ok(None),
440            false => {
441                let d = Decimal::from_str(v)
442                    .or_else(|_| Decimal::from_scientific(v))
443                    .map_err(serde::de::Error::custom)?;
444                Ok(Some(d))
445            }
446        }
447    }
448}
449
450#[cfg(feature = "serde-with-arbitrary-precision")]
451struct DecimalKey;
452
453#[cfg(feature = "serde-with-arbitrary-precision")]
454impl<'de> serde::de::Deserialize<'de> for DecimalKey {
455    fn deserialize<D>(deserializer: D) -> Result<DecimalKey, D::Error>
456    where
457        D: serde::de::Deserializer<'de>,
458    {
459        struct FieldVisitor;
460
461        impl<'de> serde::de::Visitor<'de> for FieldVisitor {
462            type Value = ();
463
464            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
465                formatter.write_str("a valid decimal field")
466            }
467
468            fn visit_str<E>(self, s: &str) -> Result<(), E>
469            where
470                E: serde::de::Error,
471            {
472                if s == DECIMAL_KEY_TOKEN {
473                    Ok(())
474                } else {
475                    Err(serde::de::Error::custom("expected field with custom name"))
476                }
477            }
478        }
479
480        deserializer.deserialize_identifier(FieldVisitor)?;
481        Ok(DecimalKey)
482    }
483}
484
485#[cfg(feature = "serde-with-arbitrary-precision")]
486pub struct DecimalFromString {
487    pub value: Decimal,
488}
489
490#[cfg(feature = "serde-with-arbitrary-precision")]
491impl<'de> serde::de::Deserialize<'de> for DecimalFromString {
492    fn deserialize<D>(deserializer: D) -> Result<DecimalFromString, D::Error>
493    where
494        D: serde::de::Deserializer<'de>,
495    {
496        struct Visitor;
497
498        impl<'de> serde::de::Visitor<'de> for Visitor {
499            type Value = DecimalFromString;
500
501            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
502                formatter.write_str("string containing a decimal")
503            }
504
505            fn visit_str<E>(self, value: &str) -> Result<DecimalFromString, E>
506            where
507                E: serde::de::Error,
508            {
509                let d = Decimal::from_str(value)
510                    .or_else(|_| Decimal::from_scientific(value))
511                    .map_err(serde::de::Error::custom)?;
512                Ok(DecimalFromString { value: d })
513            }
514        }
515
516        deserializer.deserialize_str(Visitor)
517    }
518}
519
520#[cfg(not(feature = "serde-float"))]
521impl serde::Serialize for Decimal {
522    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
523    where
524        S: serde::Serializer,
525    {
526        let value = crate::str::to_str_internal(self, true, None);
527        serializer.serialize_str(value.0.as_ref())
528    }
529}
530
531#[cfg(all(feature = "serde-float", not(feature = "serde-arbitrary-precision")))]
532impl serde::Serialize for Decimal {
533    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
534    where
535        S: serde::Serializer,
536    {
537        use num_traits::ToPrimitive;
538        serializer.serialize_f64(self.to_f64().unwrap())
539    }
540}
541
542#[cfg(all(feature = "serde-float", feature = "serde-arbitrary-precision"))]
543impl serde::Serialize for Decimal {
544    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
545    where
546        S: serde::Serializer,
547    {
548        serde_json::Number::from_str(&self.to_string())
549            .map_err(serde::ser::Error::custom)?
550            .serialize(serializer)
551    }
552}
553
554#[cfg(test)]
555mod test {
556    use super::*;
557    use serde::{Deserialize, Serialize};
558
559    #[derive(Serialize, Deserialize, Debug)]
560    struct Record {
561        amount: Decimal,
562    }
563
564    #[test]
565    #[cfg(not(feature = "serde-str"))]
566    fn deserialize_valid_decimal() {
567        let data = [
568            ("{\"amount\":\"1.234\"}", "1.234"),
569            ("{\"amount\":1234}", "1234"),
570            ("{\"amount\":1234.56}", "1234.56"),
571            ("{\"amount\":\"1.23456e3\"}", "1234.56"),
572        ];
573        for &(serialized, value) in data.iter() {
574            let result = serde_json::from_str(serialized);
575            assert!(
576                result.is_ok(),
577                "expected successful deserialization for {}. Error: {:?}",
578                serialized,
579                result.err().unwrap()
580            );
581            let record: Record = result.unwrap();
582            assert_eq!(
583                value,
584                record.amount.to_string(),
585                "expected: {}, actual: {}",
586                value,
587                record.amount
588            );
589        }
590    }
591
592    #[test]
593    #[cfg(feature = "serde-arbitrary-precision")]
594    fn deserialize_basic_decimal() {
595        let d: Decimal = serde_json::from_str("1.1234127836128763").unwrap();
596        // Typically, this would not work without this feature enabled due to rounding
597        assert_eq!(d.to_string(), "1.1234127836128763");
598    }
599
600    #[test]
601    #[should_panic]
602    fn deserialize_invalid_decimal() {
603        let serialized = "{\"amount\":\"foo\"}";
604        let _: Record = serde_json::from_str(serialized).unwrap();
605    }
606
607    #[test]
608    #[cfg(not(feature = "serde-float"))]
609    fn serialize_decimal() {
610        let record = Record {
611            amount: Decimal::new(1234, 3),
612        };
613        let serialized = serde_json::to_string(&record).unwrap();
614        assert_eq!("{\"amount\":\"1.234\"}", serialized);
615    }
616
617    #[test]
618    #[cfg(not(feature = "serde-float"))]
619    fn serialize_negative_zero() {
620        let record = Record { amount: -Decimal::ZERO };
621        let serialized = serde_json::to_string(&record).unwrap();
622        assert_eq!("{\"amount\":\"-0\"}", serialized);
623    }
624
625    #[test]
626    #[cfg(feature = "serde-float")]
627    fn serialize_decimal() {
628        let record = Record {
629            amount: Decimal::new(1234, 3),
630        };
631        let serialized = serde_json::to_string(&record).unwrap();
632        assert_eq!("{\"amount\":1.234}", serialized);
633    }
634
635    #[test]
636    #[cfg(all(feature = "serde-float", feature = "serde-arbitrary-precision"))]
637    fn serialize_decimal_roundtrip() {
638        let record = Record {
639            // 4.81 is intentionally chosen as it is unrepresentable as a floating point number, meaning this test
640            // would fail if the `serde-arbitrary-precision` was not activated.
641            amount: Decimal::new(481, 2),
642        };
643        let serialized = serde_json::to_string(&record).unwrap();
644        assert_eq!("{\"amount\":4.81}", serialized);
645        let deserialized: Record = serde_json::from_str(&serialized).unwrap();
646        assert_eq!(record.amount, deserialized.amount);
647    }
648
649    #[test]
650    #[cfg(all(feature = "serde-str", not(feature = "serde-float")))]
651    fn serialize_decimal_roundtrip() {
652        let record = Record {
653            amount: Decimal::new(481, 2),
654        };
655        let serialized = serde_json::to_string(&record).unwrap();
656        assert_eq!("{\"amount\":\"4.81\"}", serialized);
657        let deserialized: Record = serde_json::from_str(&serialized).unwrap();
658        assert_eq!(record.amount, deserialized.amount);
659    }
660
661    #[test]
662    #[cfg(all(feature = "serde-str", not(feature = "serde-float")))]
663    fn bincode_serialization_not_float() {
664        use bincode::{deserialize, serialize};
665
666        let data = [
667            "0",
668            "0.00",
669            "3.14159",
670            "-3.14159",
671            "1234567890123.4567890",
672            "-1234567890123.4567890",
673            "5233.9008808150288439427720175",
674            "-5233.9008808150288439427720175",
675        ];
676        for &raw in data.iter() {
677            let value = Decimal::from_str(raw).unwrap();
678            let encoded = serialize(&value).unwrap();
679            let decoded: Decimal = deserialize(&encoded[..]).unwrap();
680            assert_eq!(value, decoded);
681            assert_eq!(8usize + raw.len(), encoded.len());
682        }
683    }
684
685    #[test]
686    #[cfg(all(feature = "serde-str", feature = "serde-float"))]
687    fn bincode_serialization_serde_float() {
688        use bincode::{deserialize, serialize};
689
690        let data = [
691            ("0", "0"),
692            ("0.00", "0.00"),
693            ("3.14159", "3.14159"),
694            ("-3.14159", "-3.14159"),
695            ("1234567890123.4567890", "1234567890123.4568"),
696            ("-1234567890123.4567890", "-1234567890123.4568"),
697        ];
698        for &(value, expected) in data.iter() {
699            let value = Decimal::from_str(value).unwrap();
700            let expected = Decimal::from_str(expected).unwrap();
701            let encoded = serialize(&value).unwrap();
702            let decoded: Decimal = deserialize(&encoded[..]).unwrap();
703            assert_eq!(expected, decoded);
704            assert_eq!(8usize, encoded.len());
705        }
706    }
707
708    #[test]
709    #[cfg(all(feature = "serde-str", not(feature = "serde-float")))]
710    fn bincode_nested_serialization() {
711        // Issue #361
712        #[derive(Deserialize, Serialize, Debug)]
713        pub struct Foo {
714            value: Decimal,
715        }
716
717        let s = Foo {
718            value: Decimal::new(-1, 3).round_dp(0),
719        };
720        let ser = bincode::serialize(&s).unwrap();
721        let des: Foo = bincode::deserialize(&ser).unwrap();
722        assert_eq!(des.value, s.value);
723    }
724
725    #[test]
726    #[cfg(feature = "serde-with-arbitrary-precision")]
727    fn with_arbitrary_precision() {
728        #[derive(Serialize, Deserialize)]
729        pub struct ArbitraryExample {
730            #[serde(with = "crate::serde::arbitrary_precision")]
731            value: Decimal,
732        }
733
734        let value = ArbitraryExample {
735            value: Decimal::from_str("123.400").unwrap(),
736        };
737        assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":123.400}"#);
738    }
739
740    #[test]
741    #[cfg(feature = "serde-with-arbitrary-precision")]
742    fn with_arbitrary_precision_from_string() {
743        #[derive(Serialize, Deserialize)]
744        pub struct ArbitraryExample {
745            #[serde(with = "crate::serde::arbitrary_precision")]
746            value: Decimal,
747        }
748
749        let value: ArbitraryExample = serde_json::from_str(r#"{"value":"1.1234127836128763"}"#).unwrap();
750        assert_eq!(value.value.to_string(), "1.1234127836128763");
751    }
752
753    #[test]
754    #[cfg(feature = "serde-with-float")]
755    fn with_float() {
756        #[derive(Serialize, Deserialize)]
757        pub struct FloatExample {
758            #[serde(with = "crate::serde::float")]
759            value: Decimal,
760        }
761
762        let value = FloatExample {
763            value: Decimal::from_str("123.400").unwrap(),
764        };
765        assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":123.4}"#);
766    }
767
768    #[test]
769    #[cfg(feature = "serde-with-str")]
770    fn with_str() {
771        #[derive(Serialize, Deserialize)]
772        pub struct StringExample {
773            #[serde(with = "crate::serde::str")]
774            value: Decimal,
775        }
776
777        let value = StringExample {
778            value: Decimal::from_str("123.400").unwrap(),
779        };
780        assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":"123.400"}"#);
781    }
782
783    #[test]
784    #[cfg(feature = "serde-with-str")]
785    fn with_str_bincode() {
786        use bincode::{deserialize, serialize};
787
788        #[derive(Serialize, Deserialize)]
789        struct BincodeExample {
790            #[serde(with = "crate::serde::str")]
791            value: Decimal,
792        }
793
794        let data = [
795            ("0", "0"),
796            ("0.00", "0.00"),
797            ("1.234", "1.234"),
798            ("3.14159", "3.14159"),
799            ("-3.14159", "-3.14159"),
800            ("1234567890123.4567890", "1234567890123.4567890"),
801            ("-1234567890123.4567890", "-1234567890123.4567890"),
802        ];
803        for &(value, expected) in data.iter() {
804            let value = Decimal::from_str(value).unwrap();
805            let expected = Decimal::from_str(expected).unwrap();
806            let input = BincodeExample { value };
807
808            let encoded = serialize(&input).unwrap();
809            let decoded: BincodeExample = deserialize(&encoded[..]).unwrap();
810            assert_eq!(expected, decoded.value);
811        }
812    }
813
814    #[test]
815    #[cfg(feature = "serde-with-str")]
816    fn with_str_bincode_optional() {
817        use bincode::{deserialize, serialize};
818
819        #[derive(Serialize, Deserialize)]
820        struct BincodeExample {
821            #[serde(with = "crate::serde::str_option")]
822            value: Option<Decimal>,
823        }
824
825        // Some(value)
826        let value = Some(Decimal::new(1234, 3));
827        let input = BincodeExample { value };
828        let encoded = serialize(&input).unwrap();
829        let decoded: BincodeExample = deserialize(&encoded[..]).unwrap();
830        assert_eq!(value, decoded.value, "Some(value)");
831
832        // None
833        let input = BincodeExample { value: None };
834        let encoded = serialize(&input).unwrap();
835        let decoded: BincodeExample = deserialize(&encoded[..]).unwrap();
836        assert_eq!(None, decoded.value, "None");
837    }
838
839    #[test]
840    #[cfg(feature = "serde-with-str")]
841    fn with_str_optional() {
842        #[derive(Serialize, Deserialize)]
843        pub struct StringExample {
844            #[serde(with = "crate::serde::str_option")]
845            value: Option<Decimal>,
846        }
847
848        let original = StringExample {
849            value: Some(Decimal::from_str("123.400").unwrap()),
850        };
851        assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":"123.400"}"#);
852        let deserialized: StringExample = serde_json::from_str(r#"{"value":"123.400"}"#).unwrap();
853        assert_eq!(deserialized.value, original.value);
854        assert!(deserialized.value.is_some());
855        assert_eq!(deserialized.value.unwrap().unpack(), original.value.unwrap().unpack());
856
857        // Null tests
858        let original = StringExample { value: None };
859        assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#);
860        let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap();
861        assert_eq!(deserialized.value, original.value);
862        assert!(deserialized.value.is_none());
863
864        // Empty string deserialization tests
865        let original = StringExample { value: None };
866        let deserialized: StringExample = serde_json::from_str(r#"{"value":""}"#).unwrap();
867        assert_eq!(deserialized.value, original.value);
868        assert!(deserialized.value.is_none());
869    }
870
871    #[test]
872    #[cfg(feature = "serde-with-float")]
873    fn with_float_optional() {
874        #[derive(Serialize, Deserialize)]
875        pub struct StringExample {
876            #[serde(with = "crate::serde::float_option")]
877            value: Option<Decimal>,
878        }
879
880        let original = StringExample {
881            value: Some(Decimal::from_str("123.400").unwrap()),
882        };
883        assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":123.4}"#);
884        let deserialized: StringExample = serde_json::from_str(r#"{"value":123.4}"#).unwrap();
885        assert_eq!(deserialized.value, original.value);
886        assert!(deserialized.value.is_some()); // Scale is different!
887
888        // Null tests
889        let original = StringExample { value: None };
890        assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#);
891        let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap();
892        assert_eq!(deserialized.value, original.value);
893        assert!(deserialized.value.is_none());
894    }
895
896    #[test]
897    #[cfg(feature = "serde-with-arbitrary-precision")]
898    fn with_arbitrary_precision_optional() {
899        #[derive(Serialize, Deserialize)]
900        pub struct StringExample {
901            #[serde(with = "crate::serde::arbitrary_precision_option")]
902            value: Option<Decimal>,
903        }
904
905        let original = StringExample {
906            value: Some(Decimal::from_str("123.400").unwrap()),
907        };
908        assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":123.400}"#);
909        let deserialized: StringExample = serde_json::from_str(r#"{"value":123.400}"#).unwrap();
910        assert_eq!(deserialized.value, original.value);
911        assert!(deserialized.value.is_some());
912        assert_eq!(deserialized.value.unwrap().unpack(), original.value.unwrap().unpack());
913
914        // Null tests
915        let original = StringExample { value: None };
916        assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#);
917        let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap();
918        assert_eq!(deserialized.value, original.value);
919        assert!(deserialized.value.is_none());
920    }
921}