valu3/types/
array.rs

1use crate::prelude::*;
2use std::collections::{BTreeMap, HashMap};
3use std::fmt::{Debug, Display, Formatter};
4
5pub trait ArrayBehavior {
6    /// Removes the last element from the array and returns it, or `None` if the array is empty.
7    ///
8    /// # Examples
9    ///
10    /// ```no_run
11    /// use my_crate::{Array, Value};
12    ///
13    /// let mut array = Array::new();
14    /// array.push(Value::from(42));
15    ///
16    /// let popped_value = array.pop();
17    /// assert_eq!(popped_value, Some(Value::from(42)));
18    ///
19    /// let empty_array = Array::new();
20    /// let empty_popped_value = empty_array.pop();
21    /// assert_eq!(empty_popped_value, None);
22    /// ```
23    fn pop(&mut self) -> Option<Value>;
24}
25
26/// Represents an array of `Value`s.
27#[derive(Debug, Clone, PartialEq, PartialOrd)]
28pub struct Array {
29    pub values: Vec<Value>,
30}
31
32impl Array {
33    /// Creates a new empty `Array`.
34    ///
35    /// # Examples
36    ///
37    /// ```no_run
38    /// use my_crate::Array;
39    ///
40    /// let empty_array = Array::new();
41    /// assert_eq!(empty_array.len(), 0);
42    /// ```
43    pub fn new() -> Self {
44        Self { values: vec![] }
45    }
46
47    /// Returns a reference to the value at the specified index, or `None` if the index is out of bounds.
48    pub fn get(&self, index: usize) -> Option<&Value> {
49        self.values.get(index)
50    }
51
52    /// Returns a mutable reference to the value at the specified index, or `None` if the index is out of bounds.
53    pub fn get_mut(&mut self, index: usize) -> Option<&mut Value> {
54        self.values.get_mut(index)
55    }
56
57    pub fn clean(&mut self) {
58        self.values = Vec::new();
59    }
60
61    /// Appends a value to the end of the array.
62    ///
63    /// # Examples
64    ///
65    /// ```no_run
66    /// use my_crate::{Array, Value};
67    ///
68    /// let mut array = Array::new();
69    /// array.push(Value::from(42));
70    /// array.push(Value::from("hello"));
71    ///
72    /// assert_eq!(array.len(), 2);
73    /// assert_eq!(array.get(0), Some(&Value::from(42)));
74    /// assert_eq!(array.get(1), Some(&Value::from("hello")));
75    /// ```
76    pub fn push(&mut self, value: Value) {
77        self.values.push(value);
78    }
79
80    pub fn len(&self) -> usize {
81        self.values.len()
82    }
83
84    pub fn is_empty(&self) -> bool {
85        self.values.is_empty()
86    }
87}
88
89
90impl ArrayBehavior for Array {
91    fn pop(&mut self) -> Option<Value> {
92        self.values.pop()
93    }
94}
95
96impl Default for Array {
97    fn default() -> Self {
98        Self::new()
99    }
100}
101
102impl Display for Array {
103    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
104        write!(f, "[")?;
105
106        let mut iter = self.values.iter().peekable();
107        while let Some(value) = iter.next() {
108            write!(f, "{}", value)?;
109            if iter.peek().is_some() {
110                write!(f, ", ")?;
111            }
112        }
113
114        write!(f, "]")
115    }
116}
117
118impl IntoIterator for Array {
119    type Item = Value;
120    type IntoIter = std::vec::IntoIter<Self::Item>;
121
122    fn into_iter(self) -> Self::IntoIter {
123        self.values.into_iter()
124    }
125}
126
127impl<'a> IntoIterator for &'a Array {
128    type Item = &'a Value;
129    type IntoIter = std::slice::Iter<'a, Value>;
130
131    fn into_iter(self) -> Self::IntoIter {
132        self.values.iter()
133    }
134}
135
136impl<'a> IntoIterator for &'a mut Array {
137    type Item = &'a mut Value;
138    type IntoIter = std::slice::IterMut<'a, Value>;
139
140    fn into_iter(self) -> Self::IntoIter {
141        self.values.iter_mut()
142    }
143}
144
145impl From<Value> for Array {
146    fn from(value: Value) -> Self {
147        let mut array = Array::new();
148        array.push(value);
149        array
150    }
151}
152
153impl<T: Into<Value>> From<Vec<T>> for Array {
154    fn from(values: Vec<T>) -> Self {
155        let converted_values = values.into_iter().map(Into::into).collect();
156        Self {
157            values: converted_values,
158        }
159    }
160}
161
162impl<K: AsRef<str>, V: Into<Value>> From<HashMap<K, V>> for Array {
163    fn from(map: HashMap<K, V>) -> Self {
164        let values = map
165            .into_iter()
166            .map(|(k, v)| {
167                let mut object_map = HashMap::new();
168                object_map.insert(k.as_ref().to_string(), v.into());
169                Value::Object(Object::from(object_map))
170            })
171            .collect();
172        Self { values }
173    }
174}
175
176impl<K: AsRef<str>, V: Into<Value>> From<BTreeMap<K, V>> for Array {
177    fn from(map: BTreeMap<K, V>) -> Self {
178        let values = map
179            .into_iter()
180            .map(|(k, v)| {
181                let mut object_map = BTreeMap::new();
182                object_map.insert(k.as_ref().to_string(), v.into());
183                Value::Object(Object::from(object_map))
184            })
185            .collect();
186        Self { values }
187    }
188}
189
190#[cfg(test)]
191mod tests {
192    use crate::prelude::*;
193    use std::collections::{BTreeMap, HashMap};
194
195    #[test]
196    fn array_new() {
197        let array = Array::new();
198        assert!(array.is_empty());
199    }
200
201    #[test]
202    fn array_push_pop() {
203        let mut array = Array::new();
204        array.push(Value::from(42));
205        assert_eq!(array.pop(), Some(Value::from(42)));
206    }
207
208    #[test]
209    fn array_len() {
210        let mut array = Array::new();
211        array.push(Value::from(42));
212        assert_eq!(array.len(), 1);
213    }
214
215    #[test]
216    fn array_get() {
217        let mut array = Array::new();
218        array.push(Value::from(42));
219        assert_eq!(array.get(0), Some(&Value::from(42)));
220    }
221
222    #[test]
223    fn array_get_mut() {
224        let mut array = Array::new();
225        array.push(Value::from(42));
226        if let Some(value) = array.get_mut(0) {
227            *value = Value::from(84);
228        }
229        assert_eq!(array.get(0), Some(&Value::from(84)));
230    }
231
232    #[test]
233    fn array_from_value() {
234        let array = Array::from(Value::from(42));
235        assert_eq!(array.len(), 1);
236        assert_eq!(array.get(0), Some(&Value::from(42)));
237    }
238
239    #[test]
240    fn array_from_vec() {
241        let array = Array::from(vec![Value::from(42), Value::from("hello")]);
242        assert_eq!(array.len(), 2);
243        assert_eq!(array.get(0), Some(&Value::from(42)));
244        assert_eq!(array.get(1), Some(&Value::from("hello")));
245    }
246
247    #[test]
248    fn array_from_hash_map() {
249        let mut map = HashMap::new();
250        map.insert("key1", Value::from(42));
251        map.insert("key2", Value::from("hello"));
252
253        let array = Array::from(map);
254
255        assert_eq!(array.len(), 2);
256        let mut found_key1 = false;
257        let mut found_key2 = false;
258
259        for value in array {
260            if let Value::Object(object) = value {
261                if let Some(v) = object.get("key1") {
262                    assert_eq!(v, &Value::from(42));
263                    found_key1 = true;
264                } else if let Some(v) = object.get("key2") {
265                    assert_eq!(v, &Value::from("hello"));
266                    found_key2 = true;
267                }
268            }
269        }
270
271        assert!(found_key1 && found_key2);
272    }
273
274    #[test]
275    fn array_from_btree_map() {
276        let mut map = BTreeMap::new();
277        map.insert("key1", Value::from(42));
278        map.insert("key2", Value::from("hello"));
279
280        let array = Array::from(map);
281
282        assert_eq!(array.len(), 2);
283        let mut found_key1 = false;
284        let mut found_key2 = false;
285
286        for value in array {
287            if let Value::Object(object) = value {
288                if let Some(v) = object.get("key1") {
289                    assert_eq!(v, &Value::from(42));
290                    found_key1 = true;
291                } else if let Some(v) = object.get("key2") {
292                    assert_eq!(v, &Value::from("hello"));
293                    found_key2 = true;
294                }
295            }
296        }
297
298        assert!(found_key1 && found_key2);
299    }
300}