serde_utils/
quoted_u64_vec.rs1use serde::ser::SerializeSeq;
8use serde::{Deserializer, Serializer};
9use serde_derive::{Deserialize, Serialize};
10
11#[derive(Serialize, Deserialize)]
12#[serde(transparent)]
13pub struct QuotedIntWrapper {
14 #[serde(with = "crate::quoted_u64")]
15 pub int: u64,
16}
17
18pub struct QuotedIntVecVisitor;
19impl<'a> serde::de::Visitor<'a> for QuotedIntVecVisitor {
20 type Value = Vec<u64>;
21
22 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
23 write!(formatter, "a list of quoted or unquoted integers")
24 }
25
26 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
27 where
28 A: serde::de::SeqAccess<'a>,
29 {
30 let mut vec = vec![];
31
32 while let Some(val) = seq.next_element()? {
33 let val: QuotedIntWrapper = val;
34 vec.push(val.int);
35 }
36
37 Ok(vec)
38 }
39}
40
41pub fn serialize<S>(value: &[u64], serializer: S) -> Result<S::Ok, S::Error>
42where
43 S: Serializer,
44{
45 let mut seq = serializer.serialize_seq(Some(value.len()))?;
46 for &int in value {
47 seq.serialize_element(&QuotedIntWrapper { int })?;
48 }
49 seq.end()
50}
51
52pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u64>, D::Error>
53where
54 D: Deserializer<'de>,
55{
56 deserializer.deserialize_any(QuotedIntVecVisitor)
57}
58
59#[cfg(test)]
60mod test {
61 use super::*;
62
63 #[derive(Debug, Serialize, Deserialize)]
64 struct Obj {
65 #[serde(with = "crate::quoted_u64_vec")]
66 values: Vec<u64>,
67 }
68
69 #[test]
70 fn quoted_list_success() {
71 let obj: Obj = serde_json::from_str(r#"{ "values": ["1", "2", "3", "4"] }"#).unwrap();
72 assert_eq!(obj.values, vec![1, 2, 3, 4]);
73 }
74
75 #[test]
76 fn unquoted_list_success() {
77 let obj: Obj = serde_json::from_str(r#"{ "values": [1, 2, 3, 4] }"#).unwrap();
78 assert_eq!(obj.values, vec![1, 2, 3, 4]);
79 }
80
81 #[test]
82 fn mixed_list_success() {
83 let obj: Obj = serde_json::from_str(r#"{ "values": ["1", 2, "3", "4"] }"#).unwrap();
84 assert_eq!(obj.values, vec![1, 2, 3, 4]);
85 }
86
87 #[test]
88 fn empty_list_success() {
89 let obj: Obj = serde_json::from_str(r#"{ "values": [] }"#).unwrap();
90 assert!(obj.values.is_empty());
91 }
92
93 #[test]
94 fn whole_list_quoted_err() {
95 serde_json::from_str::<Obj>(r#"{ "values": "[1, 2, 3, 4]" }"#).unwrap_err();
96 }
97}