#visitor #derive #macro-derive #macro

another-visitor

允许您推导出访问者模式实现

1个不稳定版本

0.1.0 2023年1月19日

#1408Rust模式

MIT/Apache

8KB
115

another-visitor

一个crate,允许您为您的结构体推导出访问者模式实现。
由于找不到支持我想要的精确模式的现有crate,所以制作了这个。

整体流程灵感来源于ANTLR4中的实现方式

  • 访问者有一个返回类型,所有visit_*函数都返回这个类型
  • 只允许实现树中某些类型的visit函数(默认为访问所有子节点)
  • 如果您为某个类型实现了visit函数,允许您手动访问子节点
  • 允许修改(使用VisitableMut和VisitorMut)
#[derive(Visitable)]
struct A {
    b1: B,
    b2: B,
}

#[derive(Visitable)]
struct B {
    #[visit(skip)]
    msg: String
}

#[derive(Visitor)]
#[visit(A, B)]
struct AVisitor {}

impl VisitorHelper for AVisitor {
    type Output = String;
}

impl AVisitor {
    fn visit_a(&mut self, a: &A) -> <Self as VisitorHelper>::Output {
        format!("(A {} {})", self.visit(&a.b1), self.visit(&a.b2))
    }

    fn visit_b(&mut self, b: &B) -> <Self as VisitorHelper>::Output {
        format!("(B {})", b.msg)
    }
}

fn main() {
    let dat = A {
        b1: B { msg: "Hello".into() },
        b2: B { msg: "World!".into() },
    };

    let mut vis = AVisitor {};
    println!("{}", vis.visit(&dat)); // => "(A (B Hello) (B World!))"
}

更多示例请参阅another-visitor/examples

待办事项

  • 为更多类型推导Visitable(Mut)(目前只支持基本的结构体和枚举)
  • 为更多std容器实现Visitable(Mut)
  • 在proc宏中提供良好的错误消息
  • 文档
  • 发布到crates.io

此项目是一个WIP,如果您对更改或新功能有建议,请打开一个issue!

许可证

以下任一许可证下授权:

任您选择。

贡献

除非您明确说明,否则任何有意提交给工作以包含在内的贡献,根据Apache-2.0许可证的定义,均应按上述方式双许可,不附加任何额外条款或条件。

依赖项

~1.5MB
~36K SLoC