junobuild_utils/serializers/
bigint.rs1use crate::serializers::types::DocDataBigInt;
2use serde::de::{self, MapAccess, Visitor};
3use serde::ser::SerializeStruct;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use std::fmt;
6
7impl fmt::Display for DocDataBigInt {
8 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9 write!(f, "{}", self.value)
10 }
11}
12
13impl Serialize for DocDataBigInt {
14 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
15 where
16 S: Serializer,
17 {
18 let mut state = serializer.serialize_struct("DocDataBigInt", 1)?;
19 state.serialize_field("__bigint__", &self.value.to_string())?;
20 state.end()
21 }
22}
23
24impl<'de> Deserialize<'de> for DocDataBigInt {
25 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
26 where
27 D: Deserializer<'de>,
28 {
29 deserializer.deserialize_struct("DocDataBigInt", &["__bigint__"], DocDataBigIntVisitor)
30 }
31}
32
33struct DocDataBigIntVisitor;
34
35impl<'de> Visitor<'de> for DocDataBigIntVisitor {
36 type Value = DocDataBigInt;
37
38 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
39 formatter.write_str("an object with a key __bigint__")
40 }
41
42 fn visit_map<V>(self, mut map: V) -> Result<DocDataBigInt, V::Error>
43 where
44 V: MapAccess<'de>,
45 {
46 let mut value = None;
47 while let Some(key) = map.next_key::<String>()? {
48 if key == "__bigint__" {
49 if value.is_some() {
50 return Err(de::Error::duplicate_field("__bigint__"));
51 }
52 value = Some(map.next_value::<String>()?);
53 }
54 }
55 let value_str = value.ok_or_else(|| de::Error::missing_field("__bigint__"))?;
56 let bigint_value = value_str
57 .parse::<u64>()
58 .map_err(|_| de::Error::custom("Invalid format for __bigint__"))?;
59 Ok(DocDataBigInt {
60 value: bigint_value,
61 })
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use serde_json::{self};
69
70 #[test]
71 fn serialize_doc_data_bigint() {
72 let data = DocDataBigInt {
73 value: 12345678901234,
74 };
75 let s = serde_json::to_string(&data).expect("serialize");
76 assert_eq!(s, r#"{"__bigint__":"12345678901234"}"#);
77 }
78
79 #[test]
80 fn deserialize_doc_data_bigint() {
81 let s = r#"{"__bigint__":"12345678901234"}"#;
82 let data: DocDataBigInt = serde_json::from_str(s).expect("deserialize");
83 assert_eq!(data.value, 12345678901234);
84 }
85
86 #[test]
87 fn round_trip() {
88 let original = DocDataBigInt { value: u64::MAX };
89 let json = serde_json::to_string(&original).unwrap();
90 let decoded: DocDataBigInt = serde_json::from_str(&json).unwrap();
91 assert_eq!(decoded.value, original.value);
92 }
93
94 #[test]
95 fn error_on_missing_field() {
96 let err = serde_json::from_str::<DocDataBigInt>(r#"{}"#).unwrap_err();
97 assert!(
98 err.to_string().contains("missing field `__bigint__`"),
99 "got: {err}"
100 );
101 }
102
103 #[test]
104 fn error_on_duplicate_field() {
105 let s = r#"{"__bigint__":"123","__bigint__":"456"}"#;
106 let err = serde_json::from_str::<DocDataBigInt>(s).unwrap_err();
107 assert!(
108 err.to_string().contains("duplicate field `__bigint__`"),
109 "got: {err}"
110 );
111 }
112
113 #[test]
114 fn error_on_invalid_bigint_format() {
115 let s = r#"{"__bigint__":"not-a-number"}"#;
116 let err = serde_json::from_str::<DocDataBigInt>(s).unwrap_err();
117 assert!(
118 err.to_string().contains("Invalid format for __bigint__"),
119 "got: {err}"
120 );
121 }
122
123 #[test]
124 fn test_display_implementation() {
125 let data = DocDataBigInt {
126 value: 12345678901234,
127 };
128 assert_eq!(format!("{}", data), "12345678901234");
129 }
130}