#visitor #macro-derive #derive #macro

macro derive-visitor-macros

Macros for derive-visitor package

5 releases (3 breaking)

0.4.0 May 26, 2024
0.3.0 Sep 5, 2022
0.2.1 Jul 19, 2022
0.1.2 Jul 18, 2022
0.1.0 Oct 15, 2021

#2461 in Development tools

Download history 2623/week @ 2024-03-14 2462/week @ 2024-03-21 2418/week @ 2024-03-28 1358/week @ 2024-04-04 1482/week @ 2024-04-11 1683/week @ 2024-04-18 1726/week @ 2024-04-25 1360/week @ 2024-05-02 3105/week @ 2024-05-09 2223/week @ 2024-05-16 988/week @ 2024-05-23 2043/week @ 2024-05-30 2015/week @ 2024-06-06 1364/week @ 2024-06-13 2240/week @ 2024-06-20 1854/week @ 2024-06-27

7,927 downloads per month
Used in 2 crates (via derive-visitor)

MIT license

20KB
500 lines

This crate derives visitor pattern for arbitrary data structures. This pattern is particularly useful when dealing with complex nested data structures, abstract trees and hierarchies of all kinds.

The main building blocks of this crate are two derivable traits:

  • Visitor implementations walk through a data structures and accumulates some information;
  • Drive implementations are data structures that know how to drive a visitor through themselves.

Please refer to these traits' documentation for more details.

Example

use derive_visitor::{Visitor, Drive};

#[derive(Drive)]
struct Directory {
    #[drive(skip)]
    name: String,
    items: Vec<DirectoryItem>,
}

#[derive(Drive)]
enum DirectoryItem {
    File(File),
    Directory(Directory),
}

#[derive(Drive)]
struct File {
    #[drive(skip)]
    name: String,
}

#[derive(Visitor, Default)]
#[visitor(File(enter), Directory(enter))]
struct Counter {
    files: u32,
    directories: u32
}

impl Counter {
    fn enter_file(&mut self, _file: &File) {
        self.files += 1;
    }
    fn enter_directory(&mut self, _directory: &Directory) {
        self.directories += 1;
    }
}

let mut counter = Counter::default();

let example_directory = Directory {
    name: "root".into(),
    items: vec![
        DirectoryItem::Directory(
            Directory {
                name: "home".into(),
                items: vec![
                    DirectoryItem::File(File { name: "README.md".into() }),
                    DirectoryItem::File(File { name: "Star Wars.mov".into() })
                ]
            }
        ),
        DirectoryItem::Directory(
            Directory { name: "downloads".into(), items: vec![] }
        )
    ],
};

example_directory.drive(&mut counter);

assert_eq!(counter.files, 2);
assert_eq!(counter.directories, 3);

lib.rs:

This is a utility crate for derive-visitor

Dependencies

~2MB
~45K SLoC