cfx_rpc_primitives/
variadic_value.rs1use serde::{
2 de::{DeserializeOwned, Error},
3 Deserialize, Deserializer, Serialize, Serializer,
4};
5use serde_json::{from_value, Value};
6
7#[derive(Debug, PartialEq, Eq, Clone, Hash)]
8pub enum VariadicValue<T> {
9 Null,
11 Single(T),
13 Multiple(Vec<T>),
15}
16
17impl<T> Into<Option<Vec<T>>> for VariadicValue<T> {
18 fn into(self) -> Option<Vec<T>> {
19 match self {
20 VariadicValue::Null => None,
21 VariadicValue::Single(x) => Some(vec![x]),
22 VariadicValue::Multiple(xs) => Some(xs),
23 }
24 }
25}
26
27impl<T> VariadicValue<T>
28where T: DeserializeOwned
29{
30 pub fn to_vec(self) -> Vec<T> {
31 match self {
32 VariadicValue::Null => vec![],
33 VariadicValue::Single(x) => vec![x],
34 VariadicValue::Multiple(xs) => xs,
35 }
36 }
37
38 pub fn to_opt(self) -> Option<Vec<T>> {
39 match self {
40 VariadicValue::Null => None,
41 VariadicValue::Single(x) => Some(vec![x]),
42 VariadicValue::Multiple(xs) => Some(xs),
43 }
44 }
45}
46
47impl<T> VariadicValue<T> {
48 pub fn iter<'a>(
49 &'a self,
50 ) -> Box<dyn std::iter::Iterator<Item = &'a T> + 'a> {
51 match self {
52 VariadicValue::Null => Box::new(std::iter::empty()),
53 VariadicValue::Single(x) => Box::new(std::iter::once(x)),
54 VariadicValue::Multiple(xs) => Box::new(xs.iter()),
55 }
56 }
57}
58
59impl<T> Serialize for VariadicValue<T>
60where T: Serialize
61{
62 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
63 where S: Serializer {
64 match &self {
65 &VariadicValue::Null => serializer.serialize_none(),
66 &VariadicValue::Single(x) => x.serialize(serializer),
67 &VariadicValue::Multiple(xs) => xs.serialize(serializer),
68 }
69 }
70}
71
72impl<'a, T> Deserialize<'a> for VariadicValue<T>
73where T: DeserializeOwned
74{
75 fn deserialize<D>(deserializer: D) -> Result<VariadicValue<T>, D::Error>
76 where D: Deserializer<'a> {
77 let v: Value = Deserialize::deserialize(deserializer)?;
78
79 if v.is_null() {
80 return Ok(VariadicValue::Null);
81 }
82
83 from_value(v.clone())
84 .map(VariadicValue::Single)
85 .or_else(|_| from_value(v).map(VariadicValue::Multiple))
86 .map_err(|err| {
87 D::Error::custom(format!(
88 "Invalid variadic value type: {}",
89 err
90 ))
91 })
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::VariadicValue;
98 use serde_json;
99
100 #[test]
101 fn test_serialize_variadic_value() {
102 let value: VariadicValue<u64> = VariadicValue::Null;
103 let serialized_value = serde_json::to_string(&value).unwrap();
104 assert_eq!(serialized_value, "null");
105
106 let value = VariadicValue::Single(1);
107 let serialized_value = serde_json::to_string(&value).unwrap();
108 assert_eq!(serialized_value, "1");
109
110 let value = VariadicValue::Multiple(vec![1, 2, 3, 4]);
111 let serialized_value = serde_json::to_string(&value).unwrap();
112 assert_eq!(serialized_value, "[1,2,3,4]");
113
114 let value = VariadicValue::Multiple(vec![
115 VariadicValue::Null,
116 VariadicValue::Single(1),
117 VariadicValue::Multiple(vec![2, 3]),
118 VariadicValue::Single(4),
119 ]);
120 let serialized_value = serde_json::to_string(&value).unwrap();
121 assert_eq!(serialized_value, "[null,1,[2,3],4]");
122 }
123
124 #[test]
125 fn test_deserialize_variadic_value() {
126 let serialized = "null";
127 let deserialized_value: VariadicValue<u64> =
128 serde_json::from_str(serialized).unwrap();
129 assert_eq!(deserialized_value, VariadicValue::Null);
130
131 let serialized = "1";
132 let deserialized_value: VariadicValue<u64> =
133 serde_json::from_str(serialized).unwrap();
134 assert_eq!(deserialized_value, VariadicValue::Single(1));
135
136 let serialized = "[1,2,3,4]";
137 let deserialized_value: VariadicValue<u64> =
138 serde_json::from_str(serialized).unwrap();
139 assert_eq!(
140 deserialized_value,
141 VariadicValue::Multiple(vec![1, 2, 3, 4])
142 );
143 }
144}