dashu_ratio/third_party/
serde.rs1extern crate alloc;
2
3use crate::{rbig::RBig, repr::Repr, Relaxed};
4use dashu_int::{IBig, UBig};
5use serde::{
6 de::{self, Deserialize, Deserializer, SeqAccess, Visitor},
7 ser::{Serialize, SerializeStruct, Serializer},
8};
9
10const KEY_NUMER: &str = "numerator";
11const KEY_DENOM: &str = "denominator";
12const FIELDS: &[&str] = &[KEY_NUMER, KEY_DENOM];
13
14fn serialize_repr<S: Serializer>(
15 repr: &Repr,
16 serializer: S,
17 name: &'static str,
18) -> Result<S::Ok, S::Error> {
19 if serializer.is_human_readable() {
20 serializer.collect_str(repr)
22 } else {
23 let mut se = serializer.serialize_struct(name, 2)?;
25 se.serialize_field(KEY_NUMER, &repr.numerator)?;
26 se.serialize_field(KEY_DENOM, &repr.denominator)?;
27 se.end()
28 }
29}
30
31impl Serialize for RBig {
32 #[inline]
33 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
34 serialize_repr(&self.0, serializer, "RBig")
35 }
36}
37
38impl Serialize for Relaxed {
39 #[inline]
40 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
41 serialize_repr(&self.0, serializer, "Relaxed")
42 }
43}
44
45struct ReprVisitor;
46
47impl<'de> Visitor<'de> for ReprVisitor {
48 type Value = Repr;
49
50 #[inline]
51 fn expecting(&self, formatter: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
52 formatter
53 .write_str("rational number as a literal string or a struct (numerator, denominator)")
54 }
55
56 #[inline]
57 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
58 match Repr::from_str_with_radix_prefix(v) {
59 Ok((repr, _)) => Ok(repr),
60 Err(e) => Err(de::Error::custom(e)),
61 }
62 }
63
64 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
65 let err_report = || {
66 de::Error::invalid_length(
67 2,
68 &"a rational consists of two integer fields: (numerator, denominator)",
69 )
70 };
71 let numerator = seq.next_element()?.ok_or_else(err_report)?;
72 let denominator = seq.next_element()?.ok_or_else(err_report)?;
73
74 if seq.next_element::<de::IgnoredAny>()?.is_some() {
75 Err(err_report())?
76 } else {
77 Ok(Repr {
78 numerator,
79 denominator,
80 })
81 }
82 }
83
84 fn visit_map<A: serde::de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
85 let mut num: Option<IBig> = None;
86 let mut den: Option<UBig> = None;
87 while let Some(key) = map.next_key()? {
88 match key {
89 KEY_NUMER => {
90 if num.is_some() {
91 return Err(de::Error::duplicate_field(KEY_NUMER));
92 }
93 num = Some(map.next_value()?);
94 }
95 KEY_DENOM => {
96 if den.is_some() {
97 return Err(de::Error::duplicate_field(KEY_NUMER));
98 }
99 den = Some(map.next_value()?);
100 }
101 _ => return Err(de::Error::unknown_field(key, FIELDS)),
102 }
103 }
104
105 let numerator = num.ok_or_else(|| de::Error::missing_field(KEY_NUMER))?;
106 let denominator = den.ok_or_else(|| de::Error::missing_field(KEY_DENOM))?;
107 Ok(Repr {
108 numerator,
109 denominator,
110 })
111 }
112}
113
114fn deserialize_repr<'de, D: Deserializer<'de>>(
115 deserializer: D,
116 name: &'static str,
117) -> Result<Repr, D::Error> {
118 let repr = if deserializer.is_human_readable() {
119 deserializer.deserialize_str(ReprVisitor)?
120 } else {
121 deserializer.deserialize_struct(name, FIELDS, ReprVisitor)?
122 };
123 Ok(repr)
124}
125
126impl<'de> Deserialize<'de> for RBig {
127 #[inline]
128 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
129 deserialize_repr(deserializer, "RBig").map(|repr| RBig(repr.reduce()))
130 }
131}
132
133impl<'de> Deserialize<'de> for Relaxed {
134 #[inline]
135 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
136 deserialize_repr(deserializer, "Relaxed").map(|repr| Relaxed(repr.reduce2()))
137 }
138}