hcl_edit/expr/
traversal.rs1use crate::expr::Expression;
2use crate::{Decor, Decorate, Decorated, Ident};
3use std::fmt;
4use std::ops::Range;
5
6#[derive(Debug, Clone, Eq)]
8pub struct Traversal {
9 pub expr: Expression,
11 pub operators: Vec<Decorated<TraversalOperator>>,
13
14 decor: Decor,
15 span: Option<Range<usize>>,
16}
17
18impl Traversal {
19 pub fn new(
22 expr: impl Into<Expression>,
23 operators: Vec<Decorated<TraversalOperator>>,
24 ) -> Traversal {
25 Traversal {
26 expr: expr.into(),
27 operators,
28 decor: Decor::default(),
29 span: None,
30 }
31 }
32
33 pub(crate) fn despan(&mut self, input: &str) {
34 self.decor.despan(input);
35 self.expr.despan(input);
36
37 for operator in &mut self.operators {
38 operator.despan(input);
39 }
40 }
41}
42
43impl PartialEq for Traversal {
44 fn eq(&self, other: &Self) -> bool {
45 self.expr == other.expr && self.operators == other.operators
46 }
47}
48
49#[derive(Debug, Clone, PartialEq, Eq)]
51pub enum TraversalOperator {
52 AttrSplat(Decorated<Splat>),
55 FullSplat(Decorated<Splat>),
58 GetAttr(Decorated<Ident>),
60 Index(Expression),
63 LegacyIndex(Decorated<u64>),
67}
68
69impl TraversalOperator {
70 pub(crate) fn despan(&mut self, input: &str) {
71 match self {
72 TraversalOperator::AttrSplat(splat) | TraversalOperator::FullSplat(splat) => {
73 splat.decor_mut().despan(input);
74 }
75 TraversalOperator::GetAttr(ident) => ident.decor_mut().despan(input),
76 TraversalOperator::Index(expr) => expr.despan(input),
77 TraversalOperator::LegacyIndex(index) => index.decor_mut().despan(input),
78 }
79 }
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
85pub struct Splat;
86
87impl fmt::Display for Splat {
88 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89 write!(f, "*")
90 }
91}
92
93decorate_impl!(Traversal);
94span_impl!(Traversal);
95forward_decorate_impl!(TraversalOperator => { AttrSplat, FullSplat, GetAttr, Index, LegacyIndex });
96forward_span_impl!(TraversalOperator => { AttrSplat, FullSplat, GetAttr, Index, LegacyIndex });