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}