Trait derive_visitor::Drive

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

A data structure that can drive a visitor through itself.

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§

source

fn drive<V: Visitor>(&self, visitor: &mut V)

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl Drive for ()

source§

fn drive<V: Visitor>(&self, _visitor: &mut V)

source§

impl<T0> Drive for (T0,)
where T0: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T0, T1> Drive for (T0, T1)
where T0: Drive, T1: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T0, T1, T2> Drive for (T0, T1, T2)
where T0: Drive, T1: Drive, T2: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T0, T1, T2, T3> Drive for (T0, T1, T2, T3)
where T0: Drive, T1: Drive, T2: Drive, T3: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T0, T1, T2, T3, T4> Drive for (T0, T1, T2, T3, T4)
where T0: Drive, T1: Drive, T2: Drive, T3: Drive, T4: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T0, T1, T2, T3, T4, T5> Drive for (T0, T1, T2, T3, T4, T5)
where T0: Drive, T1: Drive, T2: Drive, T3: Drive, T4: Drive, T5: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T0, T1, T2, T3, T4, T5, T6> Drive for (T0, T1, T2, T3, T4, T5, T6)
where T0: Drive, T1: Drive, T2: Drive, T3: Drive, T4: Drive, T5: Drive, T6: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T0, T1, T2, T3, T4, T5, T6, T7> Drive for (T0, T1, T2, T3, T4, T5, T6, T7)
where T0: Drive, T1: Drive, T2: Drive, T3: Drive, T4: Drive, T5: Drive, T6: Drive, T7: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for Option<T>
where Option<T>: 'static, for<'a> &'a Option<T>: IntoIterator, for<'a> <&'a Option<T> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for [T]
where [T]: 'static, for<'a> &'a [T]: IntoIterator, for<'a> <&'a [T] as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for Box<T>
where T: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for BinaryHeap<T>
where BinaryHeap<T>: 'static, for<'a> &'a BinaryHeap<T>: IntoIterator, for<'a> <&'a BinaryHeap<T> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for BTreeSet<T>
where BTreeSet<T>: 'static, for<'a> &'a BTreeSet<T>: IntoIterator, for<'a> <&'a BTreeSet<T> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for LinkedList<T>
where LinkedList<T>: 'static, for<'a> &'a LinkedList<T>: IntoIterator, for<'a> <&'a LinkedList<T> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for VecDeque<T>
where VecDeque<T>: 'static, for<'a> &'a VecDeque<T>: IntoIterator, for<'a> <&'a VecDeque<T> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for Arc<T>
where T: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for Vec<T>
where Vec<T>: 'static, for<'a> &'a Vec<T>: IntoIterator, for<'a> <&'a Vec<T> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for Cell<T>
where T: Drive + Copy,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for HashSet<T>
where HashSet<T>: 'static, for<'a> &'a HashSet<T>: IntoIterator, for<'a> <&'a HashSet<T> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for Mutex<T>
where T: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T> Drive for RwLock<T>
where T: Drive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T, U> Drive for Result<T, U>
where Result<T, U>: 'static, for<'a> &'a Result<T, U>: IntoIterator, for<'a> <&'a Result<T, U> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T, U> Drive for BTreeMap<T, U>
where BTreeMap<T, U>: 'static, for<'a> &'a BTreeMap<T, U>: IntoIterator, for<'a> <&'a BTreeMap<T, U> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T, U> Drive for HashMap<T, U>
where HashMap<T, U>: 'static, for<'a> &'a HashMap<T, U>: IntoIterator, for<'a> <&'a HashMap<T, U> as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

source§

impl<T, const N: usize> Drive for [T; N]
where [T; N]: 'static, for<'a> &'a [T; N]: IntoIterator, for<'a> <&'a [T; N] as IntoIterator>::Item: DerefAndDrive,

source§

fn drive<V: Visitor>(&self, visitor: &mut V)

Implementors§