1use alloc::format;
10use core::fmt::{Display, Formatter};
11use serde::{Serializer, Deserializer};
12use crate::{DivInt, FromF64Approx};
13
14pub mod as_numerator {
35 use crate::DivInt;
36 use serde::{Deserialize, Deserializer, Serialize, Serializer};
37
38 pub fn serialize<S: Serializer, N: Serialize, const D: u64>(di: &DivInt<N, D>, s: S) -> Result<S::Ok, S::Error> {
42 di.0.serialize(s)
43 }
44
45 pub fn deserialize<'de, De, N: Deserialize<'de>, const D: u64>(d: De) -> Result<DivInt<N, D>, De::Error>
49 where
50 De: Deserializer<'de>,
51 {
52 Ok(DivInt::from_numerator(N::deserialize(d)?))
53 }
54}
55
56
57struct OutOfRangeError(f64, &'static str, u64);
58
59impl Display for OutOfRangeError {
60 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
61 f.write_str("value ")?;
62 self.0.fmt(f)?;
63 f.write_str(" does not fit into DivInt<")?;
64 f.write_str(self.1)?;
65 f.write_str(", ")?;
66 self.2.fmt(f)?;
67 f.write_str(">")
68 }
69}
70
71#[cfg(feature="serde")]
72impl<N: Copy + Into<f64>, const D: u64> ::serde::Serialize for DivInt<N, D> {
73 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74 where
75 S: ::serde::Serializer
76 {
77 self.to_f64().serialize(serializer)
78 }
79}
80
81impl<'de, N: FromF64Approx, const D: u64> ::serde::Deserialize<'de> for DivInt<N, D> {
82 fn deserialize<De>(deserializer: De) -> Result<Self, De::Error>
83 where
84 De: Deserializer<'de>
85 {
86 let f = f64::deserialize(deserializer)?;
87 match DivInt::<N, D>::from_f64_approx(f) {
88 Some(v) => Ok(v),
89 None => Err(serde::de::Error::custom(OutOfRangeError(f, core::any::type_name::<N>(), D)))
90 }
91 }
92}
93
94#[cfg(test)]
95#[cfg(feature="serde")]
96mod tests {
97 use serde::{Deserialize, Serialize};
98 use super::*;
99
100 #[test]
101 fn serialize() {
102 #[derive(Serialize, Debug, Eq, PartialEq)]
103 struct Test {
104 num: DivInt<u8, 2>,
105 }
106
107 assert_eq!(serde_json::to_string(&Test{ num: DivInt::<u8, 2>::from_numerator(3) }).unwrap(), r#"{"num":1.5}"#);
108 }
109
110 #[test]
111 fn deserialize() {
112 #[derive(Deserialize, Debug, Eq, PartialEq)]
113 struct Test {
114 num: DivInt<u8, 2>,
115 }
116
117 assert_eq!(serde_json::from_str::<Test>(r#"{"num":1.5}"#).unwrap(), Test{num: DivInt::<u8, 2>::from_numerator(3)});
118 }
119}