I have a parser toy that wants to transform AST value like SCSS nested rules, I got a problem is that when I visit every node, I would transform AST node's value computed by parent value and ancestor node value. So I use a context property of visitor to keep that value. but because I am recursively traversal, I need to change context value when iterating children like DFS, and rust's ownership would focus me clone every time when I need to change value every time, but actually, those values existed in the parent node. Is there any method I can use to reference existing value ?
use std::borrow::Cow;
struct ASTNode<'a> {
value: Cow<'a, str>,
nodes: Vec<ASTNode<'a>>
}
struct Visitor {
context: String,
}
fn some_action_to_change_ast_value_with_context(root: &mut ASTNode, context: &str ) {
// do something like root.value.push(context)
}
impl Visitor {
fn visit(&mut self, root :&mut ASTNode) {
some_action_to_change_ast_value_with_context(root, self.context.as_str());
for node in &mut root.nodes {
let last_context = self.context; // there need to be clone, can not move ownership from a reference
self.context = root.value.to_mut().clone();
self.visit(node);
self.context = last_context;
}
}
}
fn main() {
let mut root = ASTNode {
value: Cow::Borrowed("root_value"),
nodes: Vec::new()/* assume there are a a lot of nested children */
};
let mut visitor = Visitor {
context: String::new()
};
visitor.visit(&mut root);
}