another-visitor

Crates.ioanother-visitor
lib.rsanother-visitor
version0.1.0
sourcesrc
created_at2023-01-19 09:23:55.379784
updated_at2023-01-19 09:23:55.379784
descriptionLets you derive visitor pattern implementations
homepage
repositoryhttps://github.com/PieKing1215/another-visitor
max_upload_size
id762439
size14,100
David M. (PieKing1215)

documentation

README

another-visitor

A crate that lets you derive visitor pattern implementations for your structs.
Made because I couldn't find an existing crate supporting the exact pattern I wanted.

The general flow is inspired by how it works in ANTLR4:

  • Visitor has a return type that all visit_* fns return
  • Allows only implementing visit fns for some types in the tree (defaults to visiting all children)
  • Allows manually visiting children if you do implement a visit fn for a type
  • Allows mutation (using VisitableMut and 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!))"
}

See another-visitor/examples for more examples.

TODO

  • Derive Visitable(Mut) for more types (only basic structs and enums are supported)
  • Visitable(Mut) impls for more std containers
  • Good error messages in proc macros
  • Documentation
  • Publish to crates.io

This project is a WIP, if you have suggestions for changes or new features, please open an issue!

Licenses

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 14

cargo fmt