engineering_repr/
serde_support.rs1use std::{marker::PhantomData, str::FromStr};
4
5use serde::{de, Deserialize, Serialize};
6
7use crate::{EQSupported, EngineeringQuantity};
8
9impl<T: EQSupported<T>> Serialize for EngineeringQuantity<T> {
13 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
14 where
15 S: serde::Serializer,
16 {
17 let s = self.with_precision(0).to_string();
18 serializer.serialize_str(&s)
19 }
20}
21
22struct EQVisitor<U: EQSupported<U>>(PhantomData<U>);
23impl<U: EQSupported<U>> EQVisitor<U> {
24 fn new() -> Self {
25 Self(PhantomData)
26 }
27}
28impl<U: EQSupported<U> + FromStr + std::convert::TryFrom<u128> + std::convert::TryFrom<i128>>
29 de::Visitor<'_> for EQVisitor<U>
30{
31 type Value = EngineeringQuantity<U>;
32
33 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
34 where
35 E: de::Error,
36 {
37 let res = EngineeringQuantity::from_str(v);
38 res.map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &self))
39 }
40
41 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
42 where
43 E: de::Error,
44 {
45 let u = U::try_from(value).map_err(|_| de::Error::custom("failed to convert integer"))?;
46 Ok(Self::Value::from(u))
47 }
48 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
49 where
50 E: de::Error,
51 {
52 let u = U::try_from(value).map_err(|_| de::Error::custom("failed to convert integer"))?;
53 Ok(Self::Value::from(u))
54 }
55 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
56 where
57 E: de::Error,
58 {
59 self.visit_u128(value.into())
60 }
61 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
62 where
63 E: de::Error,
64 {
65 self.visit_i128(value.into())
66 }
67
68 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 formatter.write_str("an engineering quantity (1M, 4.5k, etc) or an integer")
70 }
71}
72
73impl<
77 'de,
78 T: EQSupported<T> + FromStr + std::convert::TryFrom<u128> + std::convert::TryFrom<i128>,
79 > Deserialize<'de> for EngineeringQuantity<T>
80{
81 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82 where
83 D: serde::Deserializer<'de>,
84 {
85 deserializer.deserialize_any(EQVisitor::<T>::new())
86 }
87}
88
89#[cfg(test)]
90mod test {
91 use crate::EngineeringQuantity as EQ;
92
93 #[test]
94 fn pairwise_precision() {
95 let e1 = EQ::from_raw(1_234, 2).unwrap();
96 let json = serde_json::to_string(&e1).unwrap();
97 println!("{json}");
98 let e2 = serde_json::from_str(&json).unwrap();
99 assert_eq!(e1, e2);
100 }
101
102 #[test]
103 fn type_mismatch() {
104 let _ = serde_json::from_str::<EQ<i32>>("false").expect_err("type mismatch");
105 }
106
107 #[test]
108 fn deserialize_int() {
109 let eq = serde_json::from_str::<EQ<u128>>("42768").unwrap();
110 assert_eq!(eq.to_raw(), (42768, 0));
111 let eq = serde_json::from_str::<EQ<i128>>("-42768").unwrap();
112 assert_eq!(eq.to_raw(), (-42768, 0));
113 let eq = serde_json::from_str::<EQ<u32>>("12345").unwrap();
114 assert_eq!(eq.to_raw(), (12345, 0));
115 let eq = serde_json::from_str::<EQ<i16>>("-9876").unwrap();
116 assert_eq!(eq.to_raw(), (-9876, 0));
117
118 let _ = serde_json::from_str::<EQ<u16>>("65537").unwrap_err();
120 }
121}