Expand description
Mutable HCL language item traversal.
Each method of the VisitMut
trait is a hook that can be overridden to customize the
behavior when mutating the corresponding type of language item. By default, every method
recursively visits the substructure of the AST by invoking the right visitor method of each of
its fields.
The API is modeled after
syn::visit_mut
. For an alternative
that works on shared borrows, see hcl_edit::visit
.
§Examples
Namespace all referenced variables with var.
:
use hcl_edit::expr::{Expression, Traversal, TraversalOperator};
use hcl_edit::prelude::*;
use hcl_edit::structure::Body;
use hcl_edit::visit_mut::{visit_expr_mut, VisitMut};
use hcl_edit::{Decorated, Ident};
use std::str::FromStr;
struct VariableNamespacer {
namespace: Decorated<Ident>,
}
impl VisitMut for VariableNamespacer {
fn visit_expr_mut(&mut self, expr: & mut Expression) {
if let Expression::Variable(var) = expr {
// Remove the decor and apply it to the new expression.
let decor = std::mem::take(var.decor_mut());
let namespace = Expression::Variable(self.namespace.clone());
let operators = vec![Decorated::new(TraversalOperator::GetAttr(var.clone()))];
let traversal = Traversal::new(namespace, operators);
*expr = Expression::from(traversal).decorated(decor);
} else {
// Recurse further down the AST.
visit_expr_mut(self, expr);
}
}
}
let input = r#"
// A service definition.
service {
fullname = "${namespace}/${name}"
health_endpoint = "${base_url}/health"
}
"#;
let mut body = input.parse::<Body>()?;
let mut visitor = VariableNamespacer {
namespace: Decorated::new(Ident::new("var")),
};
visitor.visit_body_mut(&mut body);
let expected = r#"
// A service definition.
service {
fullname = "${var.namespace}/${var.name}"
health_endpoint = "${var.base_url}/health"
}
"#;
assert_eq!(body.to_string(), expected);
Traits§
- Traversal to walk a mutable borrow of an HCL language item.