multiversx_chain_scenario_format/serde_raw/
value_raw.rs

1use serde::{
2    de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor},
3    ser::{Serialize, SerializeMap, SerializeSeq, Serializer},
4};
5use std::{collections::BTreeMap, fmt};
6
7#[derive(PartialEq, Eq, Clone, Debug)]
8pub enum ValueSubTree {
9    Str(String),
10    List(Vec<ValueSubTree>),
11    Map(BTreeMap<String, ValueSubTree>),
12}
13
14impl ValueSubTree {
15    pub fn is_empty_string(&self) -> bool {
16        match self {
17            ValueSubTree::Str(s) => s.is_empty(),
18            _ => false,
19        }
20    }
21
22    fn append_to_concatenated_string(&self, accumulator: &mut String) {
23        match self {
24            ValueSubTree::Str(s) => accumulator.push_str(s.as_str()),
25            ValueSubTree::List(l) => {
26                for item in l {
27                    if !(accumulator.is_empty()) {
28                        accumulator.push('|');
29                    }
30                    item.append_to_concatenated_string(accumulator);
31                }
32            }
33            ValueSubTree::Map(m) => {
34                for value in m.values() {
35                    if !(accumulator.is_empty()) {
36                        accumulator.push('|');
37                    }
38                    value.append_to_concatenated_string(accumulator);
39                }
40            }
41        }
42    }
43
44    /// Concatenates all contained values into a String.
45    pub fn to_concatenated_string(&self) -> String {
46        let mut accumulator = String::new();
47        self.append_to_concatenated_string(&mut accumulator);
48        accumulator
49    }
50}
51
52impl Default for ValueSubTree {
53    fn default() -> Self {
54        ValueSubTree::Str(String::from(""))
55    }
56}
57
58impl Serialize for ValueSubTree {
59    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60    where
61        S: Serializer,
62    {
63        match self {
64            ValueSubTree::Str(s) => serializer.serialize_str(s.as_str()),
65            ValueSubTree::List(l) => {
66                let mut seq = serializer.serialize_seq(Some(l.len()))?;
67                for item in l {
68                    seq.serialize_element(item)?;
69                }
70                seq.end()
71            }
72            ValueSubTree::Map(m) => {
73                let mut map = serializer.serialize_map(Some(m.len()))?;
74                for (k, v) in m {
75                    map.serialize_entry(k, v)?;
76                }
77                map.end()
78            }
79        }
80    }
81}
82
83pub(crate) struct ValueSubTreeVisitor;
84
85impl<'de> Visitor<'de> for ValueSubTreeVisitor {
86    type Value = ValueSubTree;
87
88    // Format a message stating what data this Visitor expects to receive.
89    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
90        formatter.write_str("serialized object JSON representation")
91    }
92
93    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
94    where
95        E: de::Error,
96    {
97        Ok(ValueSubTree::Str(String::from(value)))
98    }
99
100    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
101    where
102        A: SeqAccess<'de>,
103    {
104        let mut list = Vec::<ValueSubTree>::new();
105
106        while let Some(item) = seq.next_element()? {
107            list.push(item);
108        }
109
110        Ok(ValueSubTree::List(list))
111    }
112
113    fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
114    where
115        M: MapAccess<'de>,
116    {
117        let mut map = BTreeMap::<String, ValueSubTree>::new();
118
119        // While there are entries remaining in the input, add them
120        // into our map.
121        while let Some((key, value)) = access.next_entry()? {
122            map.insert(key, value);
123        }
124
125        Ok(ValueSubTree::Map(map))
126    }
127}
128
129impl<'de> Deserialize<'de> for ValueSubTree {
130    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
131    where
132        D: Deserializer<'de>,
133    {
134        deserializer.deserialize_any(ValueSubTreeVisitor)
135    }
136}
137
138impl fmt::Display for ValueSubTree {
139    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140        write!(f, "{}", serde_json::to_string(self).unwrap())
141    }
142}