hcl_edit/expr/
object.rs

1use crate::expr::Expression;
2use crate::{Decor, Decorate, Decorated, Ident, RawString, Span};
3use std::ops::{self, Range};
4use vecmap::map::{MutableKeys, VecMap};
5
6/// An owning iterator over the entries of an `Object`.
7///
8/// Values of this type are created by the [`into_iter`] method on [`Object`] (provided by the
9/// [`IntoIterator`] trait). See its documentation for more.
10///
11/// [`into_iter`]: IntoIterator::into_iter
12/// [`IntoIterator`]: core::iter::IntoIterator
13pub type ObjectIntoIter = Box<dyn Iterator<Item = (ObjectKey, ObjectValue)>>;
14
15/// An iterator over the entries of an `Object`.
16///
17/// Values of this type are created by the [`iter`] method on [`Object`]. See its documentation for
18/// more.
19///
20/// [`iter`]: Object::iter
21pub type ObjectIter<'a> = Box<dyn Iterator<Item = (&'a ObjectKey, &'a ObjectValue)> + 'a>;
22
23/// A mutable iterator over the entries of an `Object`.
24///
25/// Values of this type are created by the [`iter_mut`] method on [`Object`]. See its documentation
26/// for more.
27///
28/// [`iter_mut`]: Object::iter_mut
29pub type ObjectIterMut<'a> = Box<dyn Iterator<Item = (ObjectKeyMut<'a>, &'a mut ObjectValue)> + 'a>;
30
31/// Type representing a HCL object.
32#[derive(Debug, Clone, Eq, Default)]
33pub struct Object {
34    items: VecMap<ObjectKey, ObjectValue>,
35    trailing: RawString,
36    decor: Decor,
37    span: Option<Range<usize>>,
38}
39
40impl Object {
41    /// Constructs a new, empty `Object`.
42    #[inline]
43    pub fn new() -> Self {
44        Object::default()
45    }
46
47    /// Constructs a new, empty `Object` with at least the specified capacity.
48    #[inline]
49    pub fn with_capacity(capacity: usize) -> Self {
50        Object {
51            items: VecMap::with_capacity(capacity),
52            ..Default::default()
53        }
54    }
55
56    /// Returns `true` if the object contains no items.
57    #[inline]
58    pub fn is_empty(&self) -> bool {
59        self.items.is_empty()
60    }
61
62    /// Returns the number of items in the object, also referred to as its 'length'.
63    #[inline]
64    pub fn len(&self) -> usize {
65        self.items.len()
66    }
67
68    /// Clears the object, removing all items.
69    #[inline]
70    pub fn clear(&mut self) {
71        self.items.clear();
72    }
73
74    /// Return `true` if an equivalent to `key` exists in the object.
75    #[inline]
76    pub fn contains_key(&self, key: &ObjectKey) -> bool {
77        self.items.contains_key(key)
78    }
79
80    /// Return a reference to the value stored for `key`, if it is present, else `None`.
81    #[inline]
82    pub fn get(&self, key: &ObjectKey) -> Option<&ObjectValue> {
83        self.items.get(key)
84    }
85
86    /// Return a mutable reference to the value stored for `key`, if it is present, else `None`.
87    #[inline]
88    pub fn get_mut(&mut self, key: &ObjectKey) -> Option<&mut ObjectValue> {
89        self.items.get_mut(key)
90    }
91
92    /// Return references to the key-value pair stored for `key`, if it is present, else `None`.
93    #[inline]
94    pub fn get_key_value(&self, key: &ObjectKey) -> Option<(&ObjectKey, &ObjectValue)> {
95        self.items.get_key_value(key)
96    }
97
98    /// Return mutable references to the key-value pair stored for `key`, if it is present, else `None`.
99    #[inline]
100    pub fn get_key_value_mut<'a>(
101        &'a mut self,
102        key: &ObjectKey,
103    ) -> Option<(ObjectKeyMut<'a>, &'a mut ObjectValue)> {
104        self.items
105            .get_full_mut2(key)
106            .map(|(_, k, v)| (ObjectKeyMut::new(k), v))
107    }
108
109    /// Insert a key-value pair into the object.
110    ///
111    /// If an equivalent key already exists in the object: the key remains and retains in its place
112    /// in the order, its corresponding value is updated with `value` and the older value is
113    /// returned inside `Some(_)`.
114    ///
115    /// If no equivalent key existed in the object: the new key-value pair is inserted, last in
116    /// order, and `None` is returned.
117    #[inline]
118    pub fn insert(
119        &mut self,
120        key: impl Into<ObjectKey>,
121        value: impl Into<ObjectValue>,
122    ) -> Option<ObjectValue> {
123        self.items.insert(key.into(), value.into())
124    }
125
126    /// Remove the key-value pair equivalent to `key` and return its value.
127    ///
128    /// Like `Vec::remove`, the pair is removed by shifting all of the elements that follow it,
129    /// preserving their relative order. **This perturbs the index of all of those elements!**
130    #[inline]
131    pub fn remove(&mut self, key: &ObjectKey) -> Option<ObjectValue> {
132        self.items.remove(key)
133    }
134
135    /// Remove and return the key-value pair equivalent to `key`.
136    ///
137    /// Like `Vec::remove`, the pair is removed by shifting all of the elements that follow it,
138    /// preserving their relative order. **This perturbs the index of all of those elements!**
139    #[inline]
140    pub fn remove_entry(&mut self, key: &ObjectKey) -> Option<(ObjectKey, ObjectValue)> {
141        self.items.remove_entry(key)
142    }
143
144    /// An iterator visiting all key-value pairs in insertion order. The iterator element type is
145    /// `(&'a ObjectKey, &'a ObjectValue)`.
146    #[inline]
147    pub fn iter(&self) -> ObjectIter<'_> {
148        Box::new(self.items.iter())
149    }
150
151    /// An iterator visiting all key-value pairs in insertion order, with mutable references to the
152    /// values. The iterator element type is `(ObjectKeyMut<'a>, &'a mut ObjectValue)`.
153    #[inline]
154    pub fn iter_mut(&mut self) -> ObjectIterMut<'_> {
155        Box::new(
156            self.items
157                .iter_mut2()
158                .map(|(k, v)| (ObjectKeyMut::new(k), v)),
159        )
160    }
161
162    /// Return a reference to raw trailing decor before the object's closing `}`.
163    #[inline]
164    pub fn trailing(&self) -> &RawString {
165        &self.trailing
166    }
167
168    /// Set the raw trailing decor before the object's closing `}`.
169    #[inline]
170    pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
171        self.trailing = trailing.into();
172    }
173
174    pub(crate) fn despan(&mut self, input: &str) {
175        self.decor.despan(input);
176        self.trailing.despan(input);
177
178        for (key, value) in self.items.iter_mut2() {
179            key.despan(input);
180            value.despan(input);
181        }
182    }
183}
184
185impl PartialEq for Object {
186    fn eq(&self, other: &Self) -> bool {
187        self.items == other.items && self.trailing == other.trailing
188    }
189}
190
191impl From<VecMap<ObjectKey, ObjectValue>> for Object {
192    fn from(items: VecMap<ObjectKey, ObjectValue>) -> Self {
193        Object {
194            items,
195            ..Default::default()
196        }
197    }
198}
199
200impl<K, V> Extend<(K, V)> for Object
201where
202    K: Into<ObjectKey>,
203    V: Into<ObjectValue>,
204{
205    fn extend<I>(&mut self, iterable: I)
206    where
207        I: IntoIterator<Item = (K, V)>,
208    {
209        let iter = iterable.into_iter();
210        let reserve = if self.is_empty() {
211            iter.size_hint().0
212        } else {
213            (iter.size_hint().0 + 1) / 2
214        };
215        self.items.reserve(reserve);
216        iter.for_each(|(k, v)| {
217            self.insert(k, v);
218        });
219    }
220}
221
222impl<K, V> FromIterator<(K, V)> for Object
223where
224    K: Into<ObjectKey>,
225    V: Into<ObjectValue>,
226{
227    fn from_iter<I>(iterable: I) -> Self
228    where
229        I: IntoIterator<Item = (K, V)>,
230    {
231        let iter = iterable.into_iter();
232        let lower = iter.size_hint().0;
233        let mut object = Object::with_capacity(lower);
234        object.extend(iter);
235        object
236    }
237}
238
239impl IntoIterator for Object {
240    type Item = (ObjectKey, ObjectValue);
241    type IntoIter = ObjectIntoIter;
242
243    fn into_iter(self) -> Self::IntoIter {
244        Box::new(self.items.into_iter())
245    }
246}
247
248impl<'a> IntoIterator for &'a Object {
249    type Item = (&'a ObjectKey, &'a ObjectValue);
250    type IntoIter = ObjectIter<'a>;
251
252    fn into_iter(self) -> Self::IntoIter {
253        self.iter()
254    }
255}
256
257impl<'a> IntoIterator for &'a mut Object {
258    type Item = (ObjectKeyMut<'a>, &'a mut ObjectValue);
259    type IntoIter = ObjectIterMut<'a>;
260
261    fn into_iter(self) -> Self::IntoIter {
262        self.iter_mut()
263    }
264}
265
266/// Represents an object key.
267#[derive(Debug, Clone, PartialEq, Eq)]
268pub enum ObjectKey {
269    /// Represents an unquoted identifier used as object key.
270    Ident(Decorated<Ident>),
271    /// Any valid HCL expression can be an object key.
272    Expression(Expression),
273}
274
275impl ObjectKey {
276    /// Returns `true` if the object key is an identifier.
277    pub fn is_ident(&self) -> bool {
278        self.as_ident().is_some()
279    }
280
281    /// If the object key is an identifier, returns a reference to it, otherwise `None`.
282    pub fn as_ident(&self) -> Option<&Ident> {
283        match self {
284            ObjectKey::Ident(value) => Some(value.value()),
285            ObjectKey::Expression(_) => None,
286        }
287    }
288
289    /// Returns `true` if the object key is an expression.
290    pub fn is_expr(&self) -> bool {
291        self.as_expr().is_some()
292    }
293
294    /// If the object key is an expression, returns a reference to it, otherwise `None`.
295    pub fn as_expr(&self) -> Option<&Expression> {
296        match self {
297            ObjectKey::Expression(value) => Some(value),
298            ObjectKey::Ident(_) => None,
299        }
300    }
301
302    pub(crate) fn despan(&mut self, input: &str) {
303        match self {
304            ObjectKey::Ident(ident) => ident.decor_mut().despan(input),
305            ObjectKey::Expression(expr) => expr.despan(input),
306        }
307    }
308}
309
310impl From<Decorated<Ident>> for ObjectKey {
311    fn from(ident: Decorated<Ident>) -> Self {
312        ObjectKey::Ident(ident)
313    }
314}
315
316impl From<Ident> for ObjectKey {
317    fn from(ident: Ident) -> Self {
318        ObjectKey::from(Decorated::new(ident))
319    }
320}
321
322impl From<Expression> for ObjectKey {
323    fn from(expr: Expression) -> Self {
324        ObjectKey::Expression(expr)
325    }
326}
327
328/// Allows mutable access to the surrounding [`Decor`] of an [`ObjectKey`] but not to its value.
329///
330/// This type wraps the object key in the iterator returned by [`Object::iter_mut`].
331#[derive(Debug, Eq, PartialEq)]
332pub struct ObjectKeyMut<'k> {
333    key: &'k mut ObjectKey,
334}
335
336impl<'k> ObjectKeyMut<'k> {
337    pub(crate) fn new(key: &'k mut ObjectKey) -> ObjectKeyMut<'k> {
338        ObjectKeyMut { key }
339    }
340
341    /// Returns an immutable reference to the wrapped `ObjectKey`.
342    pub fn get(&self) -> &ObjectKey {
343        self.key
344    }
345}
346
347impl<'k> ops::Deref for ObjectKeyMut<'k> {
348    type Target = ObjectKey;
349
350    fn deref(&self) -> &Self::Target {
351        self.get()
352    }
353}
354
355impl<'k> Decorate for ObjectKeyMut<'k> {
356    fn decor(&self) -> &Decor {
357        self.key.decor()
358    }
359
360    fn decor_mut(&mut self) -> &mut Decor {
361        self.key.decor_mut()
362    }
363}
364
365impl<'k> Span for ObjectKeyMut<'k> {
366    fn span(&self) -> Option<Range<usize>> {
367        self.key.span()
368    }
369}
370
371/// Represents the assignment operator between an object key and its value.
372#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
373pub enum ObjectValueAssignment {
374    /// Colon (`:`) assignment operator.
375    Colon,
376    /// Equals (`=`) assignment operator.
377    #[default]
378    Equals,
379}
380
381/// Represents the character that terminates an object value.
382#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
383pub enum ObjectValueTerminator {
384    /// No terminator.
385    None,
386    /// Newline terminated.
387    Newline,
388    /// Comma terminated.
389    #[default]
390    Comma,
391}
392
393/// Represents an object value together with it's assignment operator and value terminator.
394#[derive(Debug, Clone, PartialEq, Eq)]
395pub struct ObjectValue {
396    expr: Expression,
397    assignment: ObjectValueAssignment,
398    terminator: ObjectValueTerminator,
399}
400
401impl ObjectValue {
402    /// Creates a new `ObjectValue` for an expression.
403    pub fn new(expr: impl Into<Expression>) -> ObjectValue {
404        ObjectValue {
405            expr: expr.into(),
406            assignment: ObjectValueAssignment::default(),
407            terminator: ObjectValueTerminator::default(),
408        }
409    }
410
411    /// Returns a reference to the object value's [`Expression`].
412    pub fn expr(&self) -> &Expression {
413        &self.expr
414    }
415
416    /// Returns a mutable reference to the object value's [`Expression`].
417    pub fn expr_mut(&mut self) -> &mut Expression {
418        &mut self.expr
419    }
420
421    /// Converts the object value into an [`Expression`].
422    pub fn into_expr(self) -> Expression {
423        self.expr
424    }
425
426    /// Returns the object value assignment operator.
427    pub fn assignment(&self) -> ObjectValueAssignment {
428        self.assignment
429    }
430
431    /// Sets the object value assignment operator.
432    pub fn set_assignment(&mut self, sep: ObjectValueAssignment) {
433        self.assignment = sep;
434    }
435
436    /// Returns the object value terminator.
437    pub fn terminator(&self) -> ObjectValueTerminator {
438        self.terminator
439    }
440
441    /// Sets the object value terminator.
442    pub fn set_terminator(&mut self, terminator: ObjectValueTerminator) {
443        self.terminator = terminator;
444    }
445
446    pub(crate) fn despan(&mut self, input: &str) {
447        self.expr.despan(input);
448    }
449}
450
451impl From<Expression> for ObjectValue {
452    fn from(expr: Expression) -> Self {
453        ObjectValue::new(expr)
454    }
455}
456
457decorate_impl!(Object);
458span_impl!(Object);
459forward_decorate_impl!(ObjectKey => { Ident, Expression });
460forward_span_impl!(ObjectKey => { Ident, Expression });
461
462#[cfg(test)]
463mod tests {
464    use super::*;
465    use crate::expr::Array;
466    use pretty_assertions::assert_eq;
467
468    #[test]
469    fn object_access() {
470        // Ident key.
471        let mut obj = Object::new();
472        let mut key = ObjectKey::from(Ident::new("foo"));
473        key.decorate(("/* prefix */", "/* suffix */"));
474
475        let value = ObjectValue::from(Expression::from("bar"));
476
477        obj.insert(key.clone(), value.clone());
478
479        assert_eq!(obj.get(&key), Some(&value));
480
481        key.decor_mut().clear();
482
483        assert_eq!(obj.get(&key), Some(&value));
484
485        let (key, _) = obj.remove_entry(&key).unwrap();
486        assert_eq!(key.decor().prefix(), Some(&RawString::from("/* prefix */")));
487        assert_eq!(key.decor().suffix(), Some(&RawString::from("/* suffix */")));
488
489        // Expression key.
490        let mut array = Array::new();
491        array.push("foo");
492        let mut key = ObjectKey::from(Expression::from(array));
493        key.decorate(("/* prefix */", "/* suffix */"));
494
495        let value = ObjectValue::from(Expression::from("bar"));
496
497        obj.insert(key.clone(), value.clone());
498
499        assert_eq!(obj.get(&key), Some(&value));
500
501        key.decor_mut().clear();
502
503        assert_eq!(obj.get(&key), Some(&value));
504
505        let (key, _) = obj.remove_entry(&key).unwrap();
506        assert_eq!(key.decor().prefix(), Some(&RawString::from("/* prefix */")));
507        assert_eq!(key.decor().suffix(), Some(&RawString::from("/* suffix */")));
508    }
509}