1use crate::Decimal;
2use alloc::string::ToString;
3use core::{fmt, str::FromStr};
4use num_traits::FromPrimitive;
5use serde::{self, de::Unexpected};
6
7#[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#[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#[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#[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#[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#[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#[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 #[cfg(not(feature = "serde-with-arbitrary-precision"))]
343 fn visit_f64<E>(self, value: f64) -> Result<Decimal, E>
344 where
345 E: serde::de::Error,
346 {
347 Decimal::from_str(&value.to_string()).map_err(|_| E::invalid_value(Unexpected::Float(value), &self))
348 }
349
350 #[cfg(feature = "serde-with-arbitrary-precision")]
351 fn visit_f64<E>(self, value: f64) -> Result<Decimal, E>
352 where
353 E: serde::de::Error,
354 {
355 let mut buf = zmij::Buffer::new();
356 let formatted = buf.format_finite(value);
357 Decimal::from_str(formatted)
358 .or_else(|_| Decimal::from_scientific(formatted))
359 .map_err(|_| E::invalid_value(Unexpected::Float(value), &self))
360 }
361
362 fn visit_str<E>(self, value: &str) -> Result<Decimal, E>
363 where
364 E: serde::de::Error,
365 {
366 Decimal::from_str(value)
367 .or_else(|_| Decimal::from_scientific(value))
368 .map_err(|_| E::invalid_value(Unexpected::Str(value), &self))
369 }
370
371 #[cfg(feature = "serde-with-arbitrary-precision")]
372 fn visit_map<A>(self, map: A) -> Result<Decimal, A::Error>
373 where
374 A: serde::de::MapAccess<'de>,
375 {
376 let mut map = map;
377 let value = map.next_key::<DecimalKey>()?;
378 if value.is_none() {
379 return Err(serde::de::Error::invalid_type(Unexpected::Map, &self));
380 }
381 let v: DecimalFromString = map.next_value()?;
382 Ok(v.value)
383 }
384}
385
386#[cfg(any(feature = "serde-with-float", feature = "serde-with-arbitrary-precision"))]
387struct OptionDecimalVisitor;
388
389#[cfg(any(feature = "serde-with-float", feature = "serde-with-arbitrary-precision"))]
390impl<'de> serde::de::Visitor<'de> for OptionDecimalVisitor {
391 type Value = Option<Decimal>;
392
393 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
394 formatter.write_str("a Decimal type representing a fixed-point number")
395 }
396
397 fn visit_none<E>(self) -> Result<Option<Decimal>, E>
398 where
399 E: serde::de::Error,
400 {
401 Ok(None)
402 }
403
404 #[cfg(all(feature = "serde-str", feature = "serde-float"))]
405 fn visit_some<D>(self, d: D) -> Result<Option<Decimal>, D::Error>
406 where
407 D: serde::de::Deserializer<'de>,
408 {
409 d.deserialize_any(DecimalVisitor).map(Some)
411 }
412
413 #[cfg(not(all(feature = "serde-str", feature = "serde-float")))]
414 fn visit_some<D>(self, d: D) -> Result<Option<Decimal>, D::Error>
415 where
416 D: serde::de::Deserializer<'de>,
417 {
418 <Decimal as serde::Deserialize>::deserialize(d).map(Some)
419 }
420}
421
422#[cfg(feature = "serde-with-str")]
423struct OptionDecimalStrVisitor;
424
425#[cfg(feature = "serde-with-str")]
426impl<'de> serde::de::Visitor<'de> for OptionDecimalStrVisitor {
427 type Value = Option<Decimal>;
428
429 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
430 formatter.write_str("a Decimal type representing a fixed-point number")
431 }
432
433 fn visit_none<E>(self) -> Result<Option<Decimal>, E>
434 where
435 E: serde::de::Error,
436 {
437 Ok(None)
438 }
439
440 fn visit_some<D>(self, d: D) -> Result<Option<Decimal>, D::Error>
441 where
442 D: serde::de::Deserializer<'de>,
443 {
444 d.deserialize_str(Self)
445 }
446
447 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
448 where
449 E: serde::de::Error,
450 {
451 match v.is_empty() {
452 true => Ok(None),
453 false => {
454 let d = Decimal::from_str(v)
455 .or_else(|_| Decimal::from_scientific(v))
456 .map_err(serde::de::Error::custom)?;
457 Ok(Some(d))
458 }
459 }
460 }
461}
462
463#[cfg(feature = "serde-with-arbitrary-precision")]
464struct DecimalKey;
465
466#[cfg(feature = "serde-with-arbitrary-precision")]
467impl<'de> serde::de::Deserialize<'de> for DecimalKey {
468 fn deserialize<D>(deserializer: D) -> Result<DecimalKey, D::Error>
469 where
470 D: serde::de::Deserializer<'de>,
471 {
472 struct FieldVisitor;
473
474 impl<'de> serde::de::Visitor<'de> for FieldVisitor {
475 type Value = ();
476
477 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
478 formatter.write_str("a valid decimal field")
479 }
480
481 fn visit_str<E>(self, s: &str) -> Result<(), E>
482 where
483 E: serde::de::Error,
484 {
485 if s == DECIMAL_KEY_TOKEN {
486 Ok(())
487 } else {
488 Err(serde::de::Error::custom("expected field with custom name"))
489 }
490 }
491 }
492
493 deserializer.deserialize_identifier(FieldVisitor)?;
494 Ok(DecimalKey)
495 }
496}
497
498#[cfg(feature = "serde-with-arbitrary-precision")]
499pub struct DecimalFromString {
500 pub value: Decimal,
501}
502
503#[cfg(feature = "serde-with-arbitrary-precision")]
504impl<'de> serde::de::Deserialize<'de> for DecimalFromString {
505 fn deserialize<D>(deserializer: D) -> Result<DecimalFromString, D::Error>
506 where
507 D: serde::de::Deserializer<'de>,
508 {
509 struct Visitor;
510
511 impl<'de> serde::de::Visitor<'de> for Visitor {
512 type Value = DecimalFromString;
513
514 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
515 formatter.write_str("string containing a decimal")
516 }
517
518 fn visit_str<E>(self, value: &str) -> Result<DecimalFromString, E>
519 where
520 E: serde::de::Error,
521 {
522 let d = Decimal::from_str(value)
523 .or_else(|_| Decimal::from_scientific(value))
524 .map_err(serde::de::Error::custom)?;
525 Ok(DecimalFromString { value: d })
526 }
527 }
528
529 deserializer.deserialize_str(Visitor)
530 }
531}
532
533#[cfg(not(feature = "serde-float"))]
534impl serde::Serialize for Decimal {
535 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
536 where
537 S: serde::Serializer,
538 {
539 let value = crate::str::to_str_internal(self, true, None);
540 serializer.serialize_str(value.0.as_ref())
541 }
542}
543
544#[cfg(all(feature = "serde-float", not(feature = "serde-arbitrary-precision")))]
545impl serde::Serialize for Decimal {
546 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
547 where
548 S: serde::Serializer,
549 {
550 use num_traits::ToPrimitive;
551 serializer.serialize_f64(self.to_f64().unwrap())
552 }
553}
554
555#[cfg(all(feature = "serde-float", feature = "serde-arbitrary-precision"))]
556impl serde::Serialize for Decimal {
557 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
558 where
559 S: serde::Serializer,
560 {
561 serde_json::Number::from_str(&self.to_string())
562 .map_err(serde::ser::Error::custom)?
563 .serialize(serializer)
564 }
565}
566
567#[cfg(test)]
568mod test {
569 use super::*;
570 use serde::{Deserialize, Serialize};
571
572 #[derive(Serialize, Deserialize, Debug)]
573 struct Record {
574 amount: Decimal,
575 }
576
577 #[test]
578 #[cfg(not(feature = "serde-str"))]
579 fn deserialize_valid_decimal() {
580 let data = [
581 ("{\"amount\":\"1.234\"}", "1.234"),
582 ("{\"amount\":1234}", "1234"),
583 ("{\"amount\":1234.56}", "1234.56"),
584 ("{\"amount\":\"1.23456e3\"}", "1234.56"),
585 ];
586 for &(serialized, value) in data.iter() {
587 let result = serde_json::from_str(serialized);
588 assert!(
589 result.is_ok(),
590 "expected successful deserialization for {}. Error: {:?}",
591 serialized,
592 result.err().unwrap()
593 );
594 let record: Record = result.unwrap();
595 assert_eq!(
596 value,
597 record.amount.to_string(),
598 "expected: {}, actual: {}",
599 value,
600 record.amount
601 );
602 }
603 }
604
605 #[test]
606 #[cfg(feature = "serde-arbitrary-precision")]
607 fn deserialize_basic_decimal() {
608 let d: Decimal = serde_json::from_str("1.1234127836128763").unwrap();
609 assert_eq!(d.to_string(), "1.1234127836128763");
611 }
612
613 #[test]
614 #[cfg(feature = "serde-arbitrary-precision")]
615 fn deserialize_f64_scientific_notation_from_value() {
616 let json: serde_json::Value = serde_json::from_str(r#"{"amount": 5.06e-6}"#).unwrap();
621 let record: Record = serde_json::from_value(json).unwrap();
622 assert_eq!(record.amount.to_string(), "0.00000506");
623 }
624
625 #[test]
626 #[should_panic]
627 fn deserialize_invalid_decimal() {
628 let serialized = "{\"amount\":\"foo\"}";
629 let _: Record = serde_json::from_str(serialized).unwrap();
630 }
631
632 #[test]
633 #[cfg(not(feature = "serde-float"))]
634 fn serialize_decimal() {
635 let record = Record {
636 amount: Decimal::new(1234, 3),
637 };
638 let serialized = serde_json::to_string(&record).unwrap();
639 assert_eq!("{\"amount\":\"1.234\"}", serialized);
640 }
641
642 #[test]
643 #[cfg(not(feature = "serde-float"))]
644 fn serialize_negative_zero() {
645 let record = Record { amount: -Decimal::ZERO };
646 let serialized = serde_json::to_string(&record).unwrap();
647 assert_eq!("{\"amount\":\"-0\"}", serialized);
648 }
649
650 #[test]
651 #[cfg(feature = "serde-float")]
652 fn serialize_decimal() {
653 let record = Record {
654 amount: Decimal::new(1234, 3),
655 };
656 let serialized = serde_json::to_string(&record).unwrap();
657 assert_eq!("{\"amount\":1.234}", serialized);
658 }
659
660 #[test]
661 #[cfg(all(feature = "serde-float", feature = "serde-arbitrary-precision"))]
662 fn serialize_decimal_roundtrip() {
663 let record = Record {
664 amount: Decimal::new(481, 2),
667 };
668 let serialized = serde_json::to_string(&record).unwrap();
669 assert_eq!("{\"amount\":4.81}", serialized);
670 let deserialized: Record = serde_json::from_str(&serialized).unwrap();
671 assert_eq!(record.amount, deserialized.amount);
672 }
673
674 #[test]
675 #[cfg(all(feature = "serde-float", feature = "serde-arbitrary-precision"))]
676 fn serialize_whole_number_decimal() {
677 let data = [
678 ("0", "0"),
679 ("1.0", "1.0"),
680 ("0.00", "0.00"),
681 ("1.234", "1.234"),
682 ("3.14159", "3.14159"),
683 ("-3.14159", "-3.14159"),
684 ("1234567890123.4567890", "1234567890123.4567890"),
685 ("-1234567890123.4567890", "-1234567890123.4567890"),
686 ];
687
688 for &(value, expected) in data.iter() {
689 let record = Record {
690 amount: Decimal::from_str(value).unwrap(),
691 };
692
693 let serialized = serde_json::to_string(&record).unwrap();
694 let value: serde_json::Value = serde_json::from_str(&serialized).unwrap();
695 let deserialized: Record = serde_json::from_value(value).unwrap();
696
697 assert_eq!(expected, deserialized.amount.to_string());
698 }
699 }
700
701 #[test]
702 #[cfg(all(feature = "serde-str", not(feature = "serde-float")))]
703 fn serialize_decimal_roundtrip() {
704 let record = Record {
705 amount: Decimal::new(481, 2),
706 };
707 let serialized = serde_json::to_string(&record).unwrap();
708 assert_eq!("{\"amount\":\"4.81\"}", serialized);
709 let deserialized: Record = serde_json::from_str(&serialized).unwrap();
710 assert_eq!(record.amount, deserialized.amount);
711 }
712
713 #[test]
714 #[cfg(all(feature = "serde-str", not(feature = "serde-float")))]
715 fn bincode_serialization_not_float() {
716 use bincode::{deserialize, serialize};
717
718 let data = [
719 "0",
720 "0.00",
721 "3.14159",
722 "-3.14159",
723 "1234567890123.4567890",
724 "-1234567890123.4567890",
725 "5233.9008808150288439427720175",
726 "-5233.9008808150288439427720175",
727 ];
728 for &raw in data.iter() {
729 let value = Decimal::from_str(raw).unwrap();
730 let encoded = serialize(&value).unwrap();
731 let decoded: Decimal = deserialize(&encoded[..]).unwrap();
732 assert_eq!(value, decoded);
733 assert_eq!(8usize + raw.len(), encoded.len());
734 }
735 }
736
737 #[test]
738 #[cfg(all(feature = "serde-str", feature = "serde-float"))]
739 fn bincode_serialization_serde_float() {
740 use bincode::{deserialize, serialize};
741
742 let data = [
743 ("0", "0"),
744 ("0.00", "0.00"),
745 ("3.14159", "3.14159"),
746 ("-3.14159", "-3.14159"),
747 ("1234567890123.4567890", "1234567890123.4568"),
748 ("-1234567890123.4567890", "-1234567890123.4568"),
749 ];
750 for &(value, expected) in data.iter() {
751 let value = Decimal::from_str(value).unwrap();
752 let expected = Decimal::from_str(expected).unwrap();
753 let encoded = serialize(&value).unwrap();
754 let decoded: Decimal = deserialize(&encoded[..]).unwrap();
755 assert_eq!(expected, decoded);
756 assert_eq!(8usize, encoded.len());
757 }
758 }
759
760 #[test]
761 #[cfg(all(feature = "serde-str", not(feature = "serde-float")))]
762 fn bincode_nested_serialization() {
763 #[derive(Deserialize, Serialize, Debug)]
765 pub struct Foo {
766 value: Decimal,
767 }
768
769 let s = Foo {
770 value: Decimal::new(-1, 3).round_dp(0),
771 };
772 let ser = bincode::serialize(&s).unwrap();
773 let des: Foo = bincode::deserialize(&ser).unwrap();
774 assert_eq!(des.value, s.value);
775 }
776
777 #[test]
778 #[cfg(feature = "serde-with-arbitrary-precision")]
779 fn with_arbitrary_precision() {
780 #[derive(Serialize, Deserialize)]
781 pub struct ArbitraryExample {
782 #[serde(with = "crate::serde::arbitrary_precision")]
783 value: Decimal,
784 }
785
786 let value = ArbitraryExample {
787 value: Decimal::from_str("123.400").unwrap(),
788 };
789 assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":123.400}"#);
790 }
791
792 #[test]
793 #[cfg(feature = "serde-with-arbitrary-precision")]
794 fn with_arbitrary_precision_from_string() {
795 #[derive(Serialize, Deserialize)]
796 pub struct ArbitraryExample {
797 #[serde(with = "crate::serde::arbitrary_precision")]
798 value: Decimal,
799 }
800
801 let value: ArbitraryExample = serde_json::from_str(r#"{"value":"1.1234127836128763"}"#).unwrap();
802 assert_eq!(value.value.to_string(), "1.1234127836128763");
803 }
804
805 #[test]
806 #[cfg(feature = "serde-with-float")]
807 fn with_float() {
808 #[derive(Serialize, Deserialize)]
809 pub struct FloatExample {
810 #[serde(with = "crate::serde::float")]
811 value: Decimal,
812 }
813
814 let value = FloatExample {
815 value: Decimal::from_str("123.400").unwrap(),
816 };
817 assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":123.4}"#);
818 }
819
820 #[test]
821 #[cfg(feature = "serde-with-str")]
822 fn with_str() {
823 #[derive(Serialize, Deserialize)]
824 pub struct StringExample {
825 #[serde(with = "crate::serde::str")]
826 value: Decimal,
827 }
828
829 let value = StringExample {
830 value: Decimal::from_str("123.400").unwrap(),
831 };
832 assert_eq!(&serde_json::to_string(&value).unwrap(), r#"{"value":"123.400"}"#);
833 }
834
835 #[test]
836 #[cfg(feature = "serde-with-str")]
837 fn with_str_bincode() {
838 use bincode::{deserialize, serialize};
839
840 #[derive(Serialize, Deserialize)]
841 struct BincodeExample {
842 #[serde(with = "crate::serde::str")]
843 value: Decimal,
844 }
845
846 let data = [
847 ("0", "0"),
848 ("0.00", "0.00"),
849 ("1.234", "1.234"),
850 ("3.14159", "3.14159"),
851 ("-3.14159", "-3.14159"),
852 ("1234567890123.4567890", "1234567890123.4567890"),
853 ("-1234567890123.4567890", "-1234567890123.4567890"),
854 ];
855 for &(value, expected) in data.iter() {
856 let value = Decimal::from_str(value).unwrap();
857 let expected = Decimal::from_str(expected).unwrap();
858 let input = BincodeExample { value };
859
860 let encoded = serialize(&input).unwrap();
861 let decoded: BincodeExample = deserialize(&encoded[..]).unwrap();
862 assert_eq!(expected, decoded.value);
863 }
864 }
865
866 #[test]
867 #[cfg(feature = "serde-with-str")]
868 fn with_str_bincode_optional() {
869 use bincode::{deserialize, serialize};
870
871 #[derive(Serialize, Deserialize)]
872 struct BincodeExample {
873 #[serde(with = "crate::serde::str_option")]
874 value: Option<Decimal>,
875 }
876
877 let value = Some(Decimal::new(1234, 3));
879 let input = BincodeExample { value };
880 let encoded = serialize(&input).unwrap();
881 let decoded: BincodeExample = deserialize(&encoded[..]).unwrap();
882 assert_eq!(value, decoded.value, "Some(value)");
883
884 let input = BincodeExample { value: None };
886 let encoded = serialize(&input).unwrap();
887 let decoded: BincodeExample = deserialize(&encoded[..]).unwrap();
888 assert_eq!(None, decoded.value, "None");
889 }
890
891 #[test]
892 #[cfg(feature = "serde-with-str")]
893 fn with_str_optional() {
894 #[derive(Serialize, Deserialize)]
895 pub struct StringExample {
896 #[serde(with = "crate::serde::str_option")]
897 value: Option<Decimal>,
898 }
899
900 let original = StringExample {
901 value: Some(Decimal::from_str("123.400").unwrap()),
902 };
903 assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":"123.400"}"#);
904 let deserialized: StringExample = serde_json::from_str(r#"{"value":"123.400"}"#).unwrap();
905 assert_eq!(deserialized.value, original.value);
906 assert!(deserialized.value.is_some());
907 assert_eq!(deserialized.value.unwrap().unpack(), original.value.unwrap().unpack());
908
909 let original = StringExample { value: None };
911 assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#);
912 let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap();
913 assert_eq!(deserialized.value, original.value);
914 assert!(deserialized.value.is_none());
915
916 let original = StringExample { value: None };
918 let deserialized: StringExample = serde_json::from_str(r#"{"value":""}"#).unwrap();
919 assert_eq!(deserialized.value, original.value);
920 assert!(deserialized.value.is_none());
921 }
922
923 #[test]
924 #[cfg(feature = "serde-with-float")]
925 fn with_float_optional() {
926 #[derive(Serialize, Deserialize)]
927 pub struct StringExample {
928 #[serde(with = "crate::serde::float_option")]
929 value: Option<Decimal>,
930 }
931
932 let original = StringExample {
933 value: Some(Decimal::from_str("123.400").unwrap()),
934 };
935 assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":123.4}"#);
936 let deserialized: StringExample = serde_json::from_str(r#"{"value":123.4}"#).unwrap();
937 assert_eq!(deserialized.value, original.value);
938 assert!(deserialized.value.is_some()); let original = StringExample { value: None };
942 assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#);
943 let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap();
944 assert_eq!(deserialized.value, original.value);
945 assert!(deserialized.value.is_none());
946 }
947
948 #[test]
949 #[cfg(feature = "serde-with-arbitrary-precision")]
950 fn with_arbitrary_precision_optional() {
951 #[derive(Serialize, Deserialize)]
952 pub struct StringExample {
953 #[serde(with = "crate::serde::arbitrary_precision_option")]
954 value: Option<Decimal>,
955 }
956
957 let original = StringExample {
958 value: Some(Decimal::from_str("123.400").unwrap()),
959 };
960 assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":123.400}"#);
961 let deserialized: StringExample = serde_json::from_str(r#"{"value":123.400}"#).unwrap();
962 assert_eq!(deserialized.value, original.value);
963 assert!(deserialized.value.is_some());
964 assert_eq!(deserialized.value.unwrap().unpack(), original.value.unwrap().unpack());
965
966 let original = StringExample { value: None };
968 assert_eq!(&serde_json::to_string(&original).unwrap(), r#"{"value":null}"#);
969 let deserialized: StringExample = serde_json::from_str(r#"{"value":null}"#).unwrap();
970 assert_eq!(deserialized.value, original.value);
971 assert!(deserialized.value.is_none());
972 }
973}