derive_visitor/
lib.rs

1#![warn(clippy::all)]
2#![warn(clippy::pedantic)]
3
4//! This crate derives [visitor pattern](https://rust-unofficial.github.io/patterns/patterns/behavioural/visitor.html)
5//! for arbitrary data structures. This pattern is particularly useful when dealing with complex nested data structures,
6//! abstract trees and hierarchies of all kinds.
7//!
8//! The main building blocks of this crate are two derivable traits:
9//! - [`Visitor`] and [`VisitorMut`] implementations walk through data structures and accumulate some information;
10//! - [`Drive`] and [`DriveMut`] implementations are data structures that know how to drive a visitor through themselves.
11//!
12//! Please refer to these traits' documentation for more details.
13//!
14//! ## Example
15//!
16//! ### Immutable visitor that counts items in a tree
17//! ```
18//! use derive_visitor::{Visitor, Drive};
19//!
20//! #[derive(Drive)]
21//! struct Directory {
22//!     #[drive(skip)]
23//!     name: String,
24//!     items: Vec<DirectoryItem>,
25//! }
26//!
27//! #[derive(Drive)]
28//! enum DirectoryItem {
29//!     File(File),
30//!     Directory(Directory),
31//! }
32//!
33//! #[derive(Drive)]
34//! struct File {
35//!     #[drive(skip)]
36//!     name: String,
37//! }
38//!
39//! #[derive(Visitor, Default)]
40//! #[visitor(File(enter), Directory(enter))]
41//! struct Counter {
42//!     files: u32,
43//!     directories: u32
44//! }
45//!
46//! impl Counter {
47//!     fn enter_file(&mut self, _file: &File) {
48//!         self.files += 1;
49//!     }
50//!     fn enter_directory(&mut self, _directory: &Directory) {
51//!         self.directories += 1;
52//!     }
53//! }
54//!
55//! let mut counter = Counter::default();
56//!
57//! let example_directory = Directory {
58//!     name: "root".into(),
59//!     items: vec![
60//!         DirectoryItem::Directory(
61//!             Directory {
62//!                 name: "home".into(),
63//!                 items: vec![
64//!                     DirectoryItem::File(File { name: "README.md".into() }),
65//!                     DirectoryItem::File(File { name: "Star Wars.mov".into() })
66//!                 ]
67//!             }
68//!         ),
69//!         DirectoryItem::Directory(
70//!             Directory { name: "downloads".into(), items: vec![] }
71//!         )
72//!     ],
73//! };
74//!
75//! example_directory.drive(&mut counter);
76//!
77//! assert_eq!(counter.files, 2);
78//! assert_eq!(counter.directories, 3);
79//! ```
80//!
81//! ### Mutable visitor that alters a tree
82//!
83//! ```rust
84//! use derive_visitor::{VisitorMut, DriveMut};
85//!
86//! #[derive(DriveMut)]
87//! struct Tree {
88//!     #[drive(skip)]
89//!     name: String,
90//!     children: Vec<Tree>
91//! }
92//!
93//! #[derive(VisitorMut, Default)]
94//! #[visitor(Tree(enter))]
95//! struct Renamer {
96//!     from: &'static str,
97//!     to: &'static str,
98//! }
99//!
100//! impl Renamer {
101//!     fn enter_tree(&mut self, tree: &mut Tree) {
102//!         tree.name = tree.name.replace(self.from, self.to);
103//!     }
104//! }
105//!
106//! let mut my_tree = Tree{
107//!     name: "old parent".to_string(),
108//!     children: vec![
109//!         Tree {
110//!             name: "old child".to_string(),
111//!             children: vec![]
112//!         }
113//!     ]
114//! };
115//!
116//! my_tree.drive_mut(&mut Renamer{from: "old", to: "new"});
117//!
118//! assert_eq!(my_tree.name, "new parent");
119//! assert_eq!(my_tree.children[0].name, "new child");
120//! ```
121//!
122//! ## Features
123//! - `std-types-drive` - implement [Drive](Drive) for primitive types and String type from std.
124//! It is [recommended](https://github.com/nikis05/derive-visitor/issues/3#issuecomment-1186690655) to
125//! either skip these types in your `Drive` implementation, or to wrap them with newtypes, so this feature
126//! is disabled by default. However it might be useful when driving through autogenerated structs.
127
128/// See [`Drive`].
129pub use derive_visitor_macros::Drive;
130
131/// See [`DriveMut`].
132pub use derive_visitor_macros::DriveMut;
133
134/// See [`Visitor`].
135pub use derive_visitor_macros::Visitor;
136
137/// See [`VisitorMut`].
138pub use derive_visitor_macros::VisitorMut;
139
140use std::{any::Any, cell::Cell, marker::PhantomData};
141
142#[cfg(feature = "std-types-drive")]
143use std::ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
144use std::sync::{Arc, Mutex, RwLock};
145
146/// An interface for visiting arbitrary data structures.
147///
148/// A visitor receives items that implement [Any], and can use dynamic dispatch
149/// to downcast them to particular types that it is interested in. In the classical
150/// visitor pattern, a Visitor has a set of separate methods to deal with each particular
151/// item type. This behavior can be implemented automatically using derive.
152///
153/// ## Derivable
154///
155/// This trait can be derived for any struct or enum. By default, the derived implementation
156/// does nothing. You need to explicitly specify what item types and / or events your visitor
157/// is interested in, using top-level attribute:
158///
159/// ```ignore
160/// #[derive(Visitor)]
161/// #[visitor(Directory, File)]
162/// struct NameValidator {
163///     errors: Vec<InvalidNameError>,
164/// }
165///
166/// impl NameValidator {
167///     fn enter_directory(&mut self, item: &Directory) {
168///         // ...your logic here
169///     }
170///     fn exit_directory(&mut self, item: &Directory) {
171///         // ...your logic here
172///     }
173///     fn enter_file(&mut self, item: &File) {
174///         // ...your logic here
175///     }
176///     fn exit_file(&mut self, item: &File) {
177///         // ...your logic here
178///     }
179/// }
180/// ```
181///
182/// ## Visitor functions / closures
183/// If your visitor is only interested in some particular type, you don't have to declare a struct,
184/// you can just create a visitor from a closure or a function, e.g.:
185///
186/// ```ignore
187/// let file_visitor = visitor_fn(|file: &File, event| {
188///     // ...your logic here
189/// });
190/// ```
191///
192/// See [visitor_fn](visitor_fn) and [visitor_enter_fn](visitor_enter_fn) for more info.
193///
194/// ## Macro attributes
195///
196/// If your visitor is only interested in [Event::Enter](Event::Enter) or [Event::Exit](Event::Exit),
197/// you can configure the derived implementation to only call enter / exit, respectively,
198/// on a per-type basis:
199///
200/// ```ignore
201/// #[derive(Visitor)]
202/// #[visitor(Directory(enter), File(exit))]
203/// struct NameValidator {
204///     errors: Vec<InvalidNameError>,
205/// }
206///
207/// impl NameValidator {
208///     fn enter_directory(&mut self, item: &Directory) {
209///         // ...your logic here
210///     }
211///     fn exit_file(&mut self, item: &File) {
212///         // ...your logic here
213///     }
214/// }
215/// ```
216///
217/// You can also provide custom method names for each type / event:
218///
219/// ```ignore
220/// #[derive(Visitor)]
221/// #[visitor(Directory(enter="custom_enter_directory", exit="custom_exit_directory"), File)]
222/// struct NameValidator {
223///     errors: Vec<InvalidNameError>,
224/// }
225///
226/// impl NameValidator {
227///     fn custom_enter_directory(&mut self, item: &Directory) {
228///         // ...your logic here
229///     }
230///     fn custom_exit_directory(&mut self, item: &Directory) {
231///         // ...your logic here
232///     }
233///     fn enter_file(&mut self, item: &File) {
234///         // ...your logic here
235///     }
236///     fn exit_file(&mut self, item: &File) {
237///         // ...your logic here
238///     }
239/// }
240/// ```
241pub trait Visitor {
242    fn visit(&mut self, item: &dyn Any, event: Event);
243}
244
245/// An interface for visiting data structures and mutating them during the visit.
246///
247/// It works exactly the same as [Visitor], but it takes a mutable reference to the visited element.
248///
249/// ```rust
250/// use derive_visitor::VisitorMut;
251///
252/// struct Chain {
253///     next: Option<Box<Chain>>
254/// }
255///
256/// #[derive(VisitorMut)]
257/// #[visitor(Chain(enter))]
258/// struct ChainCutter;
259///
260/// impl ChainCutter {
261///     fn enter_chain(&mut self, item: &mut Chain) {
262///         item.next = None
263///     }
264/// }
265/// ```
266pub trait VisitorMut {
267    fn visit(&mut self, item: &mut dyn Any, event: Event);
268}
269
270/// Create a visitor that only visits items of some specific type from a function or a closure.
271///
272/// ## Example
273/// ```rust
274/// use derive_visitor::{visitor_fn, Drive};
275/// # #[derive(Drive)] struct File;
276/// File.drive(&mut visitor_fn(|file: &File, event| {
277///     // ...your logic here
278/// }));
279/// ```
280pub fn visitor_fn<T, F: FnMut(&T, Event)>(fun: F) -> FnVisitor<T, F> {
281    FnVisitor {
282        marker: PhantomData,
283        fun,
284    }
285}
286
287/// Create a visitor that only visits items and mutates them with the given function
288///
289/// ## Example
290/// ```rust
291/// use derive_visitor::{visitor_fn_mut, DriveMut};
292/// # #[derive(DriveMut)] struct File;
293/// File.drive_mut(&mut visitor_fn_mut(|file: &mut File, event| {
294///     // ...your logic here
295/// }));
296/// ```
297pub fn visitor_fn_mut<T, F: FnMut(&mut T, Event)>(fun: F) -> FnVisitor<T, F> {
298    FnVisitor {
299        marker: PhantomData,
300        fun,
301    }
302}
303
304/// Similar to [visitor_fn](visitor_fn), but the closure will only be called on [Event::Enter](Event::Enter).
305pub fn visitor_enter_fn<T, F: FnMut(&T)>(mut fun: F) -> FnVisitor<T, impl FnMut(&T, Event)> {
306    visitor_fn(move |item, event| {
307        if let Event::Enter = event {
308            fun(item);
309        }
310    })
311}
312
313/// Similar to [`visitor_fn_mut`], but the closure will only be called on [Event::Enter](Event::Enter).
314pub fn visitor_enter_fn_mut<T, F: FnMut(&mut T)>(
315    mut fun: F,
316) -> FnVisitor<T, impl FnMut(&mut T, Event)> {
317    visitor_fn_mut(move |item, event| {
318        if let Event::Enter = event {
319            fun(item);
320        }
321    })
322}
323
324/// Type returned by [visitor_fn](visitor_fn).
325pub struct FnVisitor<T, F> {
326    marker: PhantomData<T>,
327    fun: F,
328}
329
330impl<T: Any, F: FnMut(&T, Event)> Visitor for FnVisitor<T, F> {
331    fn visit(&mut self, item: &dyn Any, event: Event) {
332        if let Some(item) = <dyn Any>::downcast_ref::<T>(item) {
333            let fun = &mut self.fun;
334            fun(item, event);
335        }
336    }
337}
338
339impl<T: Any, F: FnMut(&mut T, Event)> VisitorMut for FnVisitor<T, F> {
340    fn visit(&mut self, item: &mut dyn Any, event: Event) {
341        if let Some(item) = <dyn Any>::downcast_mut::<T>(item) {
342            let fun = &mut self.fun;
343            fun(item, event);
344        }
345    }
346}
347
348/// Defines whether an item is being entered or exited by a visitor.
349pub enum Event {
350    Enter,
351    Exit,
352}
353
354/// A data structure that can drive a [visitor](Visitor) through itself.
355///
356/// Derive or implement this trait for any type that you want to be able to
357/// traverse with a visitor.
358///
359/// `Drive` is implemented for most wrapping and collection types from [std],
360/// as long as their wrapped / item type implements `Drive`.
361///
362/// ## Derivable
363///
364/// This trait can be derived for any struct or enum.
365/// By default, the derived implementation will make the visitor enter `self`,
366/// then drive it through every field of `self`, and finally make it exit `self`:
367///
368/// ```ignore
369/// #[derive(Drive)]
370/// struct Directory {
371///     #[drive(skip)]
372///     name: String,
373///     items: Vec<DirectoryItem>,
374/// }
375///
376/// #[derive(Drive)]
377/// enum DirectoryItem {
378///     File(File),
379///     Directory(Directory),
380/// }
381///
382/// #[derive(Drive)]
383/// struct File {
384///     #[drive(skip)]
385///     name: String,
386/// }
387/// ```
388///
389/// ## Implementing manually
390///
391/// The following code snippet is roughly equivalent to the implementations
392/// that would be derived in the example above:
393///
394/// ```ignore
395/// impl Drive for Directory {
396///     fn drive<V: Visitor>(&self, visitor: &mut V) {
397///         visitor.visit(self, Event::Enter);
398///         self.items.drive(visitor);
399///         visitor.visit(self, Event::Exit);
400///     }
401/// }
402///
403/// impl Drive for DirectoryItem {
404///     fn drive<V: Visitor>(&self, visitor: &mut V) {
405///         visitor.visit(self, Event::Enter);
406///         match self {
407///             Self::File(file) => {
408///                 file.drive(visitor);
409///             },
410///             Self::Directory(directory) => {
411///                 directory.drive(visitor);
412///             }
413///         }
414///         visitor.visit(self, Event::Exit);
415///     }
416/// }
417///
418/// impl Drive for File {
419///     fn drive<V: Visitor>(&self, visitor: &mut V) {
420///         visitor.visit(self, Event::Enter);
421///         visitor.visit(self, Event::Exit);
422///     }
423/// }
424/// ```
425///
426/// ## Macro attributes
427///
428/// The derived implementation of `Drive` can be customized using attributes:
429///
430/// ### `#[drive(skip)]`
431///
432/// If applied to a field or an enum variant, the derived implementation won't
433/// drive the visitor through that field / variant.
434///
435/// If applied to a struct or an enum itself, the derived implementation will
436/// drive the visitor through the type's fields / variants, but won't make it
437/// enter or exit the type itself.
438///
439/// ### `#[drive(with="path")]`
440///
441/// Drive a visitor through a field using a custom function.
442/// The function must have the following signature: `fn<V: Visitor>(&T, &mut V)`.
443///
444/// In the example below, this attribute is used to customize driving through a [Vec]:
445///
446/// ```ignore
447/// #[derive(Drive)]
448/// struct Book {
449///     title: String,
450///     #[drive(with="reverse_vec_driver")]
451///     chapters: Vec<Chapter>,
452/// }
453///
454/// fn reverse_vec_driver<T, V: Visitor>(vec: &Vec<T>, visitor: &mut V) {
455///     for item in vec.iter().rev() {
456///         item.drive(visitor);
457///     }
458/// }
459/// ```
460pub trait Drive: Any {
461    fn drive<V: Visitor>(&self, visitor: &mut V);
462}
463
464/// Drive a [`VisitorMut`] over this datastructure.
465///
466/// This is equivalent to [`Drive`], but gives the possibility to mutate the datastructure as it is visited.
467///
468/// ## Example
469///
470/// ```rust
471/// use derive_visitor::{DriveMut, Event, visitor_fn_mut};
472///
473/// #[derive(DriveMut, Default)]
474/// struct Node{ children: Vec<Node> }
475///
476/// let mut node = Node{children: vec![Node::default(), Node::default()]};
477///
478/// node.drive_mut(&mut visitor_fn_mut(|n: &mut Node, event|
479///     // Mutate the element on exit so that we are not driven to the newly created elements
480///     if let Event::Exit = event {
481///         n.children.resize_with(3, Default::default);
482///     }
483/// ));
484///
485/// // We have driven over all the initial nodes...
486/// assert_eq!(node.children.len(), 3);
487/// assert_eq!(node.children[0].children.len(), 3);
488/// assert_eq!(node.children[1].children.len(), 3);
489/// // ... but not over the newly created ones
490/// assert_eq!(node.children[2].children.len(), 0);
491/// ```
492pub trait DriveMut: Any {
493    fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V);
494}
495
496// Helper trait to the generic `IntoIterator` Drive impl
497trait DerefAndDrive {
498    fn deref_and_drive<V: Visitor>(self, visitor: &mut V);
499}
500
501// Drives a VisitorMut over a mutable reference
502trait DerefAndDriveMut {
503    fn deref_and_drive_mut<V: VisitorMut>(self, visitor: &mut V);
504}
505
506// Most collections iterate over item references, this is the trait impl that handles that case
507impl<T: Drive> DerefAndDrive for &T {
508    fn deref_and_drive<V: Visitor>(self, visitor: &mut V) {
509        self.drive(visitor);
510    }
511}
512
513impl<T: DriveMut> DerefAndDriveMut for &mut T {
514    fn deref_and_drive_mut<V: VisitorMut>(self, visitor: &mut V) {
515        self.drive_mut(visitor);
516    }
517}
518
519// Map-like collections iterate over item references pairs
520impl<TK: Drive, TV: Drive> DerefAndDrive for (&TK, &TV) {
521    fn deref_and_drive<V: Visitor>(self, visitor: &mut V) {
522        self.0.drive(visitor);
523        self.1.drive(visitor);
524    }
525}
526
527// Map-like collections have mutable iterators that allow mutating only the value, not the key
528impl<TK, TV: DriveMut> DerefAndDriveMut for (TK, &mut TV) {
529    fn deref_and_drive_mut<V: VisitorMut>(self, visitor: &mut V) {
530        self.1.drive_mut(visitor);
531    }
532}
533
534// Implement Drive and DriveMut for container types in standard library.
535macro_rules! impl_drive_for_into_iterator {
536    ( $type:ty ; $($generics:tt)+ ) => {
537        impl< $($generics)+ > Drive for $type
538        where
539            $type: 'static,
540            for<'a> &'a $type: IntoIterator,
541            for<'a> <&'a $type as IntoIterator>::Item: DerefAndDrive,
542        {
543            fn drive<V: Visitor>(&self, visitor: &mut V) {
544                for item in self {
545                    item.deref_and_drive(visitor);
546                }
547            }
548        }
549
550        impl< $($generics)+ > DriveMut for $type
551        where
552            $type: 'static,
553            for<'a> &'a mut $type: IntoIterator,
554            for<'a> <&'a mut $type as IntoIterator>::Item: DerefAndDriveMut,
555        {
556            fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
557                for item in self {
558                    item.deref_and_drive_mut(visitor);
559                }
560            }
561        }
562    };
563}
564
565impl_drive_for_into_iterator! { [T] ; T }
566impl_drive_for_into_iterator! { Vec<T> ; T }
567impl_drive_for_into_iterator! { std::collections::BTreeSet<T> ; T }
568impl_drive_for_into_iterator! { std::collections::BinaryHeap<T> ; T }
569impl_drive_for_into_iterator! { std::collections::HashSet<T> ; T }
570impl_drive_for_into_iterator! { std::collections::LinkedList<T> ; T }
571impl_drive_for_into_iterator! { std::collections::VecDeque<T> ; T }
572impl_drive_for_into_iterator! { Option<T> ; T }
573impl_drive_for_into_iterator! { Result<T, U> ; T, U }
574impl_drive_for_into_iterator! { std::collections::BTreeMap<T, U> ; T, U }
575impl_drive_for_into_iterator! { std::collections::HashMap<T, U> ; T, U }
576impl_drive_for_into_iterator! { [T; N] ; T, const N: usize }
577
578impl<T> Drive for Box<T>
579where
580    T: Drive,
581{
582    fn drive<V: Visitor>(&self, visitor: &mut V) {
583        (**self).drive(visitor);
584    }
585}
586
587impl<T> DriveMut for Box<T>
588where
589    T: DriveMut,
590{
591    fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
592        (**self).drive_mut(visitor);
593    }
594}
595
596impl<T> Drive for Arc<T>
597where
598    T: Drive,
599{
600    fn drive<V: Visitor>(&self, visitor: &mut V) {
601        (**self).drive(visitor);
602    }
603}
604
605impl<T> Drive for Mutex<T>
606where
607    T: Drive,
608{
609    fn drive<V: Visitor>(&self, visitor: &mut V) {
610        let lock = self.lock().unwrap();
611        lock.drive(visitor);
612    }
613}
614
615impl<T> Drive for RwLock<T>
616where
617    T: Drive,
618{
619    fn drive<V: Visitor>(&self, visitor: &mut V) {
620        let lock = self.read().unwrap();
621        lock.drive(visitor);
622    }
623}
624
625impl<T> DriveMut for Arc<Mutex<T>>
626where
627    T: DriveMut,
628{
629    fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
630        let mut lock = self.lock().unwrap();
631        lock.drive_mut(visitor);
632    }
633}
634
635impl<T> DriveMut for Arc<RwLock<T>>
636where
637    T: DriveMut,
638{
639    fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
640        let mut lock = self.write().unwrap();
641        lock.drive_mut(visitor);
642    }
643}
644
645impl<T> Drive for Cell<T>
646where
647    T: Drive + Copy,
648{
649    fn drive<V: Visitor>(&self, visitor: &mut V) {
650        self.get().drive(visitor);
651    }
652}
653
654impl<T> DriveMut for Cell<T>
655where
656    T: DriveMut,
657{
658    fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
659        self.get_mut().drive_mut(visitor);
660    }
661}
662
663impl Drive for () {
664    fn drive<V: Visitor>(&self, _visitor: &mut V) {}
665}
666
667impl DriveMut for () {
668    fn drive_mut<V: VisitorMut>(&mut self, _visitor: &mut V) {}
669}
670
671macro_rules! tuple_impls {
672    ( $( $( $type:ident ),+ => $( $field:tt ),+ )+ ) => {
673        $(
674            impl<$( $type ),+> Drive for ($($type,)+)
675            where
676                $(
677                    $type: Drive
678                ),+
679            {
680                fn drive<V: Visitor>(&self, visitor: &mut V) {
681                    $(
682                        self.$field.drive(visitor);
683                    )+
684                }
685            }
686
687            impl<$( $type ),+> DriveMut for ($($type,)+)
688            where
689                $(
690                    $type: DriveMut
691                ),+
692            {
693                fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
694                    $(
695                        self.$field.drive_mut(visitor);
696                    )+
697                }
698            }
699        )+
700    };
701}
702
703tuple_impls! {
704    T0 => 0
705    T0, T1 => 0, 1
706    T0, T1, T2 => 0, 1, 2
707    T0, T1, T2, T3 => 0, 1, 2, 3
708    T0, T1, T2, T3, T4 => 0, 1, 2, 3, 4
709    T0, T1, T2, T3, T4, T5 => 0, 1, 2, 3, 4, 5
710    T0, T1, T2, T3, T4, T5, T6 => 0, 1, 2, 3, 4, 5, 6
711    T0, T1, T2, T3, T4, T5, T6, T7 => 0, 1, 2, 3, 4, 5, 6, 7
712}
713
714#[cfg(feature = "std-types-drive")]
715macro_rules! trivial_impl {
716    ( $type:ty ) => {
717        impl Drive for $type {
718            fn drive<V: Visitor>(&self, visitor: &mut V) {
719                visitor.visit(self, Event::Enter);
720                visitor.visit(self, Event::Exit);
721            }
722        }
723        impl DriveMut for $type {
724            fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
725                visitor.visit(self, Event::Enter);
726                visitor.visit(self, Event::Exit);
727            }
728        }
729    };
730}
731
732#[cfg(not(feature = "std-types-drive"))]
733macro_rules! trivial_impl {
734    ( $type:ident ) => {};
735}
736
737trivial_impl!(u8);
738trivial_impl!(u16);
739trivial_impl!(u32);
740trivial_impl!(u64);
741trivial_impl!(u128);
742trivial_impl!(usize);
743
744trivial_impl!(i8);
745trivial_impl!(i16);
746trivial_impl!(i32);
747trivial_impl!(i64);
748trivial_impl!(i128);
749trivial_impl!(isize);
750
751trivial_impl!(f32);
752trivial_impl!(f64);
753
754trivial_impl!(char);
755trivial_impl!(bool);
756
757trivial_impl!(String);
758
759#[cfg(feature = "std-types-drive")]
760mod drive_ranges {
761    use super::*;
762    use std::ops::*;
763
764    impl<T: Drive> Drive for Range<T> {
765        fn drive<V: Visitor>(&self, visitor: &mut V) {
766            self.start.drive(visitor);
767            self.end.drive(visitor);
768        }
769    }
770
771    impl<T: DriveMut> DriveMut for Range<T> {
772        fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
773            self.start.drive_mut(visitor);
774            self.end.drive_mut(visitor);
775        }
776    }
777
778    impl<T: Drive> Drive for RangeTo<T> {
779        fn drive<V: Visitor>(&self, visitor: &mut V) {
780            self.end.drive(visitor);
781        }
782    }
783
784    impl<T: DriveMut> DriveMut for RangeTo<T> {
785        fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
786            self.end.drive_mut(visitor);
787        }
788    }
789
790    impl<T: Drive> Drive for RangeToInclusive<T> {
791        fn drive<V: Visitor>(&self, visitor: &mut V) {
792            self.end.drive(visitor);
793        }
794    }
795
796    impl<T: DriveMut> DriveMut for RangeToInclusive<T> {
797        fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
798            self.end.drive_mut(visitor);
799        }
800    }
801
802    impl<T: Drive> Drive for RangeFrom<T> {
803        fn drive<V: Visitor>(&self, visitor: &mut V) {
804            self.start.drive(visitor);
805        }
806    }
807
808    impl<T: DriveMut> DriveMut for RangeFrom<T> {
809        fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
810            self.start.drive_mut(visitor);
811        }
812    }
813
814    impl<T: Drive> Drive for RangeInclusive<T> {
815        fn drive<V: Visitor>(&self, visitor: &mut V) {
816            self.start().drive(visitor);
817            self.end().drive(visitor);
818        }
819    }
820
821    // Unfortunately, RangeInclusive does not give mutable access to its bounds, so we have to
822    // add a T: Default constraint in order to have something to put into the old range while we are changing the bounds.
823    // This should not cause issues in practice, because ranges of non-Default values are rare.
824    impl<T: DriveMut> DriveMut for RangeInclusive<T>
825    where
826        T: Default,
827    {
828        fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
829            let placeholder = RangeInclusive::new(T::default(), T::default());
830            let bounds = std::mem::replace(self, placeholder);
831            let mut tuple = bounds.into_inner();
832            tuple.drive_mut(visitor);
833            *self = RangeInclusive::new(tuple.0, tuple.1);
834        }
835    }
836}