1use ::serde::{Deserialize, Deserializer, Serializer};
8use num_traits::{AsPrimitive, ToPrimitive};
9
10use crate::Q;
11
12pub mod as_f32 {
16 use super::*;
17
18 pub fn serialize<S, T, A, const F: i8>(q: &Q<T, A, F>, serializer: S) -> Result<S::Ok, S::Error>
20 where
21 S: Serializer,
22 Q<T, A, F>: ToPrimitive,
23 {
24 serializer.serialize_f32(
25 q.to_f32()
26 .ok_or_else(|| ::serde::ser::Error::custom("fixed-point value is not finite"))?,
27 )
28 }
29
30 pub fn deserialize<'de, D, T, A, const F: i8>(deserializer: D) -> Result<Q<T, A, F>, D::Error>
32 where
33 D: Deserializer<'de>,
34 f32: AsPrimitive<Q<T, A, F>>,
35 Q<T, A, F>: Copy + 'static,
36 {
37 f32::deserialize(deserializer).map(Q::from_f32)
38 }
39}
40
41pub mod as_f64 {
45 use super::*;
46
47 pub fn serialize<S, T, A, const F: i8>(q: &Q<T, A, F>, serializer: S) -> Result<S::Ok, S::Error>
49 where
50 S: Serializer,
51 Q<T, A, F>: ToPrimitive,
52 {
53 serializer.serialize_f64(
54 q.to_f64()
55 .ok_or_else(|| ::serde::ser::Error::custom("fixed-point value is not finite"))?,
56 )
57 }
58
59 pub fn deserialize<'de, D, T, A, const F: i8>(deserializer: D) -> Result<Q<T, A, F>, D::Error>
61 where
62 D: Deserializer<'de>,
63 f64: AsPrimitive<Q<T, A, F>>,
64 Q<T, A, F>: Copy + 'static,
65 {
66 f64::deserialize(deserializer).map(Q::from_f64)
67 }
68}
69
70#[cfg(test)]
71mod test {
72 use super::*;
73 use ::serde::{Deserialize, Serialize};
74
75 #[derive(Debug, Deserialize, PartialEq, Serialize)]
76 struct F32 {
77 #[serde(with = "as_f32")]
78 value: crate::Q<i32, i64, 3>,
79 }
80
81 #[derive(Debug, Deserialize, PartialEq, Serialize)]
82 struct F64 {
83 #[serde(with = "as_f64")]
84 value: crate::Q<i32, i64, 3>,
85 }
86
87 #[test]
88 fn as_f32_uses_scaled_value() {
89 let value = F32 {
90 value: crate::Q::new(1),
91 };
92 let mut out = [0; 32];
93 let len = serde_json_core::to_slice(&value, &mut out).unwrap();
94 let json = &out[..len];
95 assert_eq!(json, br#"{"value":0.125}"#);
96 assert_eq!(serde_json_core::from_slice::<F32>(json).unwrap().0, value);
97 }
98
99 #[test]
100 fn as_f64_uses_scaled_value() {
101 let value = F64 {
102 value: crate::Q::new(1),
103 };
104 let mut out = [0; 32];
105 let len = serde_json_core::to_slice(&value, &mut out).unwrap();
106 let json = &out[..len];
107 assert_eq!(json, br#"{"value":0.125}"#);
108 assert_eq!(serde_json_core::from_slice::<F64>(json).unwrap().0, value);
109 }
110}