dashu_ratio/third_party/
serde.rs

1extern 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        // serialize to formatted string if the serializer is human readable
21        serializer.collect_str(repr)
22    } else {
23        // otherwise serialize as a (numerator, denominator) struct
24        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}