Trait derive_visitor::Drive[][src]

pub trait Drive: Any {
    fn drive<V: Visitor>(&self, visitor: &mut V);
}
Expand description

A data structure that can drive a visitor through iself.

Derive or implement this trait for any type that you want to be able to traverse with a visitor.

Drive is implemented for most wrapping and collection types from std, as long as their wrapped / item type implements Drive.

Derivable

This trait can be derived for any struct or enum. By default, the derived implementation will make the visitor enter self, then drive it through every field of self, and finally make it exit self:

#[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,
}

Implementing manually

The following code snippet is roughly equivalent to the implementations that would be derived in the example above:

impl Drive for Directory {
    fn drive<V: Visitor>(&self, visitor: &mut V) {
        visitor.visit(self, Event::Enter);
        self.items.drive(visitor);
        visitor.visit(self, Event::Exit);
    }
}

impl Drive for DirectoryItem {
    fn drive<V: Visitor>(&self, visitor: &mut V) {
        visitor.visit(self, Event::Enter);
        match self {
            Self::File(file) => {
                file.drive(visitor);
            },
            Self::Directory(directory) => {
                directory.drive(visitor);
            }
        }
        visitor.visit(self, Event::Exit);
    }
}

impl Drive for File {
    fn drive<V: Visitor>(&self, visitor: &mut V) {
        visitor.visit(self, Event::Enter);
        visitor.visit(self, Event::Exit);
    }
}

Macro attributes

The derived implementation of Drive can be customized using attributes:

#[drive(skip)]

If applied to a field or an enum variant, the derived implementation won’t drive the visitor through that field / variant.

If applied to a struct or an enum itself, the derived implementation will drive the visitor through the type’s fields / variants, but won’t make it enter or exit the type itself.

#[drive(with="path")]

Drive a visitor through a field using a custom function. The function must have the following signature: fn<V: Visitor>(&T, &mut V).

In the example below, this attribute is used to customize driving through a Vec:

#[derive(Drive)]
struct Book {
    title: String,
    #[drive(with="reverse_vec_driver")]
    chapters: Vec<Chapter>,
}

fn reverse_vec_driver<T, V: Visitor>(vec: &Vec<T>, visitor: &mut V) {
    for item in vec.iter().rev() {
        item.drive(visitor);
    }
}

Required methods

Implementations on Foreign Types

Implementors