fixed/
serdeize.rs

1// Copyright © 2018–2025 Trevor Spiteri
2
3// This library is free software: you can redistribute it and/or
4// modify it under the terms of either
5//
6//   * the Apache License, Version 2.0 or
7//   * the MIT License
8//
9// at your option.
10//
11// You should have recieved copies of the Apache License and the MIT
12// License along with the library. If not, see
13// <https://www.apache.org/licenses/LICENSE-2.0> and
14// <https://opensource.org/licenses/MIT>.
15
16use crate::types::extra::{LeEqU8, LeEqU16, LeEqU32, LeEqU64, LeEqU128};
17use crate::{
18    FixedI8, FixedI16, FixedI32, FixedI64, FixedI128, FixedU8, FixedU16, FixedU32, FixedU64,
19    FixedU128, Unwrapped, Wrapping,
20};
21use serde::de::{Deserialize, Deserializer, Error as DeError};
22use serde::ser::{Serialize, Serializer};
23#[cfg(not(feature = "serde-str"))]
24use {
25    core::fmt::{Formatter, Result as FmtResult},
26    serde::de::{MapAccess, SeqAccess, Visitor},
27    serde::ser::SerializeStruct,
28};
29
30macro_rules! serde_fixed {
31    ($Fixed:ident($LeEqU:ident) is $TBits:ident name $Name:expr) => {
32        impl<Frac: $LeEqU> Serialize for $Fixed<Frac> {
33            #[cfg(not(feature = "serde-str"))]
34            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
35                let bits = self.to_bits();
36                let mut state = serializer.serialize_struct($Name, 1)?;
37                state.serialize_field("bits", &bits)?;
38                state.end()
39            }
40
41            #[cfg(feature = "serde-str")]
42            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
43                if serializer.is_human_readable() {
44                    self.to_string().serialize(serializer)
45                } else {
46                    self.to_bits().serialize(serializer)
47                }
48            }
49        }
50
51        impl<Frac: $LeEqU> Serialize for Wrapping<$Fixed<Frac>> {
52            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
53                self.0.serialize(serializer)
54            }
55        }
56
57        impl<Frac: $LeEqU> Serialize for Unwrapped<$Fixed<Frac>> {
58            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
59                self.0.serialize(serializer)
60            }
61        }
62
63        impl<'de, Frac: $LeEqU> Deserialize<'de> for $Fixed<Frac> {
64            #[cfg(not(feature = "serde-str"))]
65            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
66                struct FixedVisitor;
67
68                impl<'de> Visitor<'de> for FixedVisitor {
69                    type Value = $TBits;
70
71                    fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
72                        formatter.write_str("struct ")?;
73                        formatter.write_str($Name)
74                    }
75
76                    fn visit_seq<V: SeqAccess<'de>>(self, mut seq: V) -> Result<$TBits, V::Error> {
77                        let bits = seq
78                            .next_element()?
79                            .ok_or_else(|| DeError::invalid_length(0, &self))?;
80                        Ok(bits)
81                    }
82
83                    fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<$TBits, V::Error> {
84                        let mut bits = None;
85                        while let Some(key) = map.next_key()? {
86                            match key {
87                                Field::Bits => {
88                                    if bits.is_some() {
89                                        return Err(DeError::duplicate_field("bits"));
90                                    }
91                                    bits = Some(map.next_value()?);
92                                }
93                            }
94                        }
95                        let bits = bits.ok_or_else(|| DeError::missing_field("bits"))?;
96                        Ok(bits)
97                    }
98                }
99
100                let bits = deserializer.deserialize_struct($Name, FIELDS, FixedVisitor)?;
101                Ok($Fixed::from_bits(bits))
102            }
103
104            #[cfg(feature = "serde-str")]
105            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
106                if deserializer.is_human_readable() {
107                    String::deserialize(deserializer)?
108                        .parse()
109                        .map_err(|e| DeError::custom(format_args!("parse error: {e}")))
110                } else {
111                    $TBits::deserialize(deserializer).map($Fixed::from_bits)
112                }
113            }
114        }
115
116        impl<'de, Frac: $LeEqU> Deserialize<'de> for Wrapping<$Fixed<Frac>> {
117            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
118                $Fixed::deserialize(deserializer).map(Wrapping)
119            }
120        }
121
122        impl<'de, Frac: $LeEqU> Deserialize<'de> for Unwrapped<$Fixed<Frac>> {
123            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
124                $Fixed::deserialize(deserializer).map(Unwrapped)
125            }
126        }
127    };
128}
129
130serde_fixed! { FixedI8(LeEqU8) is i8 name "FixedI8" }
131serde_fixed! { FixedI16(LeEqU16) is i16 name "FixedI16" }
132serde_fixed! { FixedI32(LeEqU32) is i32 name "FixedI32" }
133serde_fixed! { FixedI64(LeEqU64) is i64 name "FixedI64" }
134serde_fixed! { FixedI128(LeEqU128) is i128 name "FixedI128" }
135serde_fixed! { FixedU8(LeEqU8) is u8 name "FixedU8" }
136serde_fixed! { FixedU16(LeEqU16) is u16 name "FixedU16" }
137serde_fixed! { FixedU32(LeEqU32) is u32 name "FixedU32" }
138serde_fixed! { FixedU64(LeEqU64) is u64 name "FixedU64" }
139serde_fixed! { FixedU128(LeEqU128) is u128 name "FixedU128" }
140
141#[cfg(not(feature = "serde-str"))]
142const FIELDS: &[&str] = &["bits"];
143
144#[cfg(not(feature = "serde-str"))]
145enum Field {
146    Bits,
147}
148
149#[cfg(not(feature = "serde-str"))]
150impl<'de> Deserialize<'de> for Field {
151    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Field, D::Error> {
152        struct FieldVisitor;
153
154        impl Visitor<'_> for FieldVisitor {
155            type Value = Field;
156
157            fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
158                formatter.write_str("`bits`")
159            }
160
161            fn visit_str<E: DeError>(self, value: &str) -> Result<Field, E> {
162                match value {
163                    "bits" => Ok(Field::Bits),
164                    _ => Err(DeError::unknown_field(value, FIELDS)),
165                }
166            }
167        }
168
169        deserializer.deserialize_identifier(FieldVisitor)
170    }
171}