1#[cfg(feature = "fold")]
2pub mod fold {
3 use crate::fold::Fold;
4 use crate::punctuated::{Pair, Punctuated};
5 use proc_macro2::Span;
6
7 pub trait FoldHelper {
8 type Item;
9 fn lift<F>(self, f: F) -> Self
10 where
11 F: FnMut(Self::Item) -> Self::Item;
12 }
13
14 impl<T> FoldHelper for Vec<T> {
15 type Item = T;
16 fn lift<F>(self, f: F) -> Self
17 where
18 F: FnMut(Self::Item) -> Self::Item,
19 {
20 self.into_iter().map(f).collect()
21 }
22 }
23
24 impl<T, U> FoldHelper for Punctuated<T, U> {
25 type Item = T;
26 fn lift<F>(self, mut f: F) -> Self
27 where
28 F: FnMut(Self::Item) -> Self::Item,
29 {
30 self.into_pairs()
31 .map(Pair::into_tuple)
32 .map(|(t, u)| Pair::new(f(t), u))
33 .collect()
34 }
35 }
36
37 pub fn tokens_helper<F: Fold + ?Sized, S: Spans>(folder: &mut F, spans: &S) -> S {
38 spans.fold(folder)
39 }
40
41 pub trait Spans {
42 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self;
43 }
44
45 impl Spans for Span {
46 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self {
47 folder.fold_span(*self)
48 }
49 }
50
51 impl Spans for [Span; 1] {
52 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self {
53 [folder.fold_span(self[0])]
54 }
55 }
56
57 impl Spans for [Span; 2] {
58 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self {
59 [folder.fold_span(self[0]), folder.fold_span(self[1])]
60 }
61 }
62
63 impl Spans for [Span; 3] {
64 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self {
65 [
66 folder.fold_span(self[0]),
67 folder.fold_span(self[1]),
68 folder.fold_span(self[2]),
69 ]
70 }
71 }
72}
73
74#[cfg(feature = "visit")]
75pub mod visit {
76 use crate::visit::Visit;
77 use proc_macro2::Span;
78
79 pub fn tokens_helper<'ast, V: Visit<'ast> + ?Sized, S: Spans>(visitor: &mut V, spans: &S) {
80 spans.visit(visitor);
81 }
82
83 pub trait Spans {
84 fn visit<'ast, V: Visit<'ast> + ?Sized>(&self, visitor: &mut V);
85 }
86
87 impl Spans for Span {
88 fn visit<'ast, V: Visit<'ast> + ?Sized>(&self, visitor: &mut V) {
89 visitor.visit_span(self);
90 }
91 }
92
93 impl Spans for [Span; 1] {
94 fn visit<'ast, V: Visit<'ast> + ?Sized>(&self, visitor: &mut V) {
95 visitor.visit_span(&self[0]);
96 }
97 }
98
99 impl Spans for [Span; 2] {
100 fn visit<'ast, V: Visit<'ast> + ?Sized>(&self, visitor: &mut V) {
101 visitor.visit_span(&self[0]);
102 visitor.visit_span(&self[1]);
103 }
104 }
105
106 impl Spans for [Span; 3] {
107 fn visit<'ast, V: Visit<'ast> + ?Sized>(&self, visitor: &mut V) {
108 visitor.visit_span(&self[0]);
109 visitor.visit_span(&self[1]);
110 visitor.visit_span(&self[2]);
111 }
112 }
113}
114
115#[cfg(feature = "visit-mut")]
116pub mod visit_mut {
117 use crate::visit_mut::VisitMut;
118 use proc_macro2::Span;
119
120 pub fn tokens_helper<V: VisitMut + ?Sized, S: Spans>(visitor: &mut V, spans: &mut S) {
121 spans.visit_mut(visitor);
122 }
123
124 pub trait Spans {
125 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V);
126 }
127
128 impl Spans for Span {
129 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
130 visitor.visit_span_mut(self);
131 }
132 }
133
134 impl Spans for [Span; 1] {
135 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
136 visitor.visit_span_mut(&mut self[0]);
137 }
138 }
139
140 impl Spans for [Span; 2] {
141 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
142 visitor.visit_span_mut(&mut self[0]);
143 visitor.visit_span_mut(&mut self[1]);
144 }
145 }
146
147 impl Spans for [Span; 3] {
148 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
149 visitor.visit_span_mut(&mut self[0]);
150 visitor.visit_span_mut(&mut self[1]);
151 visitor.visit_span_mut(&mut self[2]);
152 }
153 }
154}
155