cfx_rpc_primitives/
variadic_value.rs

1use 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    /// None
10    Null,
11    /// Single
12    Single(T),
13    /// List
14    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}