hcl_edit/expr/
array.rs

1use crate::expr::Expression;
2use crate::{Decor, RawString};
3use std::ops::Range;
4
5/// An owning iterator over the values of an `Array`.
6///
7/// Values of this type are created by the [`into_iter`] method on [`Array`] (provided by the
8/// [`IntoIterator`] trait). See its documentation for more.
9///
10/// [`into_iter`]: IntoIterator::into_iter
11/// [`IntoIterator`]: core::iter::IntoIterator
12pub type IntoIter = Box<dyn Iterator<Item = Expression>>;
13
14/// An iterator over the values of an `Array`.
15///
16/// Values of this type are created by the [`iter`] method on [`Array`]. See its documentation for
17/// more.
18///
19/// [`iter`]: Array::iter
20pub type Iter<'a> = Box<dyn Iterator<Item = &'a Expression> + 'a>;
21
22/// A mutable iterator over the values of an `Array`.
23///
24/// Values of this type are created by the [`iter_mut`] method on [`Array`]. See its documentation
25/// for more.
26///
27/// [`iter_mut`]: Array::iter_mut
28pub type IterMut<'a> = Box<dyn Iterator<Item = &'a mut Expression> + 'a>;
29
30/// Type representing a HCL array.
31#[derive(Debug, Clone, Eq, Default)]
32pub struct Array {
33    values: Vec<Expression>,
34    trailing: RawString,
35    trailing_comma: bool,
36    decor: Decor,
37    span: Option<Range<usize>>,
38}
39
40impl Array {
41    /// Constructs a new, empty `Array`.
42    #[inline]
43    pub fn new() -> Self {
44        Array::default()
45    }
46
47    /// Constructs a new, empty `Array` with at least the specified capacity.
48    #[inline]
49    pub fn with_capacity(capacity: usize) -> Self {
50        Array {
51            values: Vec::with_capacity(capacity),
52            ..Default::default()
53        }
54    }
55
56    /// Returns `true` if the array contains no elements.
57    #[inline]
58    pub fn is_empty(&self) -> bool {
59        self.values.is_empty()
60    }
61
62    /// Returns the number of elements in the array, also referred to as its 'length'.
63    #[inline]
64    pub fn len(&self) -> usize {
65        self.values.len()
66    }
67
68    /// Clears the array, removing all values.
69    #[inline]
70    pub fn clear(&mut self) {
71        self.values.clear();
72    }
73
74    /// Returns a reference to the value at the given index, or `None` if the index is out of
75    /// bounds.
76    #[inline]
77    pub fn get(&self, index: usize) -> Option<&Expression> {
78        self.values.get(index)
79    }
80
81    /// Returns a mutable reference to the value at the given index, or `None` if the index is out
82    /// of bounds.
83    #[inline]
84    pub fn get_mut(&mut self, index: usize) -> Option<&mut Expression> {
85        self.values.get_mut(index)
86    }
87
88    /// Inserts an element at position `index` within the array, shifting all elements after it to
89    /// the right.
90    ///
91    /// # Panics
92    ///
93    /// Panics if `index > len`.
94    #[inline]
95    pub fn insert(&mut self, index: usize, value: impl Into<Expression>) {
96        self.values.insert(index, value.into());
97    }
98
99    /// Appends an element to the back of the array.
100    ///
101    /// # Panics
102    ///
103    /// Panics if the new capacity exceeds `isize::MAX` bytes.
104    #[inline]
105    pub fn push(&mut self, value: impl Into<Expression>) {
106        self.values.push(value.into());
107    }
108
109    /// Removes the last element from the array and returns it, or [`None`] if it is empty.
110    #[inline]
111    pub fn pop(&mut self) -> Option<Expression> {
112        self.values.pop()
113    }
114
115    /// Removes and returns the element at position `index` within the array, shifting all elements
116    /// after it to the left.
117    ///
118    /// Like `Vec::remove`, the element is removed by shifting all of the elements that follow it,
119    /// preserving their relative order. **This perturbs the index of all of those elements!**
120    ///
121    /// # Panics
122    ///
123    /// Panics if `index` is out of bounds.
124    #[inline]
125    pub fn remove(&mut self, index: usize) -> Expression {
126        self.values.remove(index)
127    }
128
129    /// An iterator visiting all values in insertion order. The iterator element type is `&'a
130    /// Expression`.
131    #[inline]
132    pub fn iter(&self) -> Iter<'_> {
133        Box::new(self.values.iter())
134    }
135
136    /// An iterator visiting all values in insertion order, with mutable references to the values.
137    /// The iterator element type is `&'a mut Expression`.
138    #[inline]
139    pub fn iter_mut(&mut self) -> IterMut<'_> {
140        Box::new(self.values.iter_mut())
141    }
142
143    /// Return a reference to raw trailing decor before the array's closing `]`.
144    #[inline]
145    pub fn trailing(&self) -> &RawString {
146        &self.trailing
147    }
148
149    /// Set the raw trailing decor before the array's closing `]`.
150    #[inline]
151    pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
152        self.trailing = trailing.into();
153    }
154
155    /// Returns `true` if the array uses a trailing comma.
156    #[inline]
157    pub fn trailing_comma(&self) -> bool {
158        self.trailing_comma
159    }
160
161    /// Set whether the array will use a trailing comma.
162    #[inline]
163    pub fn set_trailing_comma(&mut self, yes: bool) {
164        self.trailing_comma = yes;
165    }
166
167    pub(crate) fn despan(&mut self, input: &str) {
168        self.decor.despan(input);
169        self.trailing.despan(input);
170
171        for value in &mut self.values {
172            value.despan(input);
173        }
174    }
175}
176
177impl PartialEq for Array {
178    fn eq(&self, other: &Self) -> bool {
179        self.values == other.values
180            && self.trailing_comma == other.trailing_comma
181            && self.trailing == other.trailing
182    }
183}
184
185impl From<Vec<Expression>> for Array {
186    fn from(values: Vec<Expression>) -> Self {
187        Array {
188            values,
189            ..Default::default()
190        }
191    }
192}
193
194impl<T> Extend<T> for Array
195where
196    T: Into<Expression>,
197{
198    fn extend<I>(&mut self, iterable: I)
199    where
200        I: IntoIterator<Item = T>,
201    {
202        let iter = iterable.into_iter();
203        let reserve = if self.is_empty() {
204            iter.size_hint().0
205        } else {
206            (iter.size_hint().0 + 1) / 2
207        };
208        self.values.reserve(reserve);
209        iter.for_each(|v| self.push(v));
210    }
211}
212
213impl<T> FromIterator<T> for Array
214where
215    T: Into<Expression>,
216{
217    fn from_iter<I>(iterable: I) -> Self
218    where
219        I: IntoIterator<Item = T>,
220    {
221        let iter = iterable.into_iter();
222        let lower = iter.size_hint().0;
223        let mut array = Array::with_capacity(lower);
224        array.extend(iter);
225        array
226    }
227}
228
229impl IntoIterator for Array {
230    type Item = Expression;
231    type IntoIter = IntoIter;
232
233    fn into_iter(self) -> Self::IntoIter {
234        Box::new(self.values.into_iter())
235    }
236}
237
238impl<'a> IntoIterator for &'a Array {
239    type Item = &'a Expression;
240    type IntoIter = Iter<'a>;
241
242    fn into_iter(self) -> Self::IntoIter {
243        self.iter()
244    }
245}
246
247impl<'a> IntoIterator for &'a mut Array {
248    type Item = &'a mut Expression;
249    type IntoIter = IterMut<'a>;
250
251    fn into_iter(self) -> Self::IntoIter {
252        self.iter_mut()
253    }
254}
255
256decorate_impl!(Array);
257span_impl!(Array);