Пониженные черты внутри Rc для манипуляции AST
Я пытаюсь манипулировать AST в Rust. Будет много манипуляций, и я хочу, чтобы мои деревья были неизменными, поэтому для экономии времени все ссылки будутRc
s.
Узлы моего дерева будут выглядеть так:
enum Condition {
Equals(Rc<Expression>, Rc<Expression>),
LessThan(Rc<Expression>, Rc<Expression>),
...
}
enum Expression {
Plus(Rc<Expression>, Rc<Expression>),
...
}
Я хочу заменить случайный узел данного типа другим узлом того же типа. Для выполнения общих операций над деревьями я сделал особенность:
trait AstNode {
fn children(&self) -> Vec<Rc<AstNode>>;
}
И все узлы реализуют это. Это позволяет мне обходить дерево без необходимости деструктурировать каждый тип узла для каждой операции, просто вызываяchildren()
.
Я также хочу клонировать узел, обновляя только один из его дочерних элементов и оставляя остальные на месте. Предположим, что мне удалось сгенерировать узлы правильного конкретного типа (и я рад, что программа запаниковала, если я ошибаюсь). Я добавлю следующий метод в черту:
trait AstNode {
fn clone_with_children(&self, new_children: Vec<Rc<AstNode>>) -> Self
where Self: Sized;
}
Мой план состоит в том, чтобы забрать детей, возвращенныхchilden()
замените один из них и позвонитеclone_with_children()
построить узел того же варианта перечисления, но с заменой одного узла.
Моя проблема в том, как написатьclone_with_children()
.
Мне нужно убитьRc<AstNode>
вRc<Expression>
(или что у вас есть), сохраняя при этомRc
То же самое, но ни одна из найденных мной библиотек не может это сделать.
Возможно ли то, что я хочу, или я должен сделать это совершенно иначе?