blob: f91ebcd2dab85b2d81d94e90f405deca66c1c4b6 [file] [log] [blame]
David Tolnayf60f4262017-12-28 19:17:58 -05001#[cfg(feature = "fold")]
2pub mod fold {
David Tolnay61037c62018-01-05 16:21:03 -08003 use punctuated::{Element, Punctuated};
David Tolnaycc0f0372017-12-28 19:11:04 -05004 use fold::Folder;
5 use proc_macro2::Span;
David Tolnayf60f4262017-12-28 19:17:58 -05006
7 pub trait FoldHelper {
8 type Item;
David Tolnay61037c62018-01-05 16:21:03 -08009 fn lift<F>(self, f: F) -> Self
10 where
11 F: FnMut(Self::Item) -> Self::Item;
David Tolnayf60f4262017-12-28 19:17:58 -050012 }
13
14 impl<T> FoldHelper for Vec<T> {
15 type Item = T;
David Tolnay61037c62018-01-05 16:21:03 -080016 fn lift<F>(self, f: F) -> Self
17 where
18 F: FnMut(Self::Item) -> Self::Item,
19 {
David Tolnayf60f4262017-12-28 19:17:58 -050020 self.into_iter().map(f).collect()
21 }
22 }
23
David Tolnayf2cfd722017-12-31 18:02:51 -050024 impl<T, U> FoldHelper for Punctuated<T, U> {
David Tolnayf60f4262017-12-28 19:17:58 -050025 type Item = T;
David Tolnay61037c62018-01-05 16:21:03 -080026 fn lift<F>(self, mut f: F) -> Self
27 where
28 F: FnMut(Self::Item) -> Self::Item,
29 {
David Tolnay6eff4da2018-01-01 20:27:45 -080030 self.into_elements()
David Tolnay660fd1f2017-12-31 01:52:57 -050031 .map(Element::into_tuple)
32 .map(|(t, u)| Element::new(f(t), u))
33 .collect()
David Tolnayf60f4262017-12-28 19:17:58 -050034 }
35 }
David Tolnaycc0f0372017-12-28 19:11:04 -050036
37 pub fn tokens_helper<F: Folder + ?Sized, S: Spans>(folder: &mut F, spans: &S) -> S {
38 spans.fold(folder)
39 }
40
41 pub trait Spans {
42 fn fold<F: Folder + ?Sized>(&self, folder: &mut F) -> Self;
43 }
44
45 impl Spans for Span {
46 fn fold<F: Folder + ?Sized>(&self, folder: &mut F) -> Self {
47 folder.fold_span(*self)
48 }
49 }
50
51 impl Spans for [Span; 1] {
52 fn fold<F: Folder + ?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: Folder + ?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: Folder + ?Sized>(&self, folder: &mut F) -> Self {
David Tolnay61037c62018-01-05 16:21:03 -080065 [
66 folder.fold_span(self[0]),
67 folder.fold_span(self[1]),
68 folder.fold_span(self[2]),
69 ]
David Tolnaycc0f0372017-12-28 19:11:04 -050070 }
71 }
72}
73
74#[cfg(feature = "visit")]
75pub mod visit {
76 use proc_macro2::Span;
77 use visit::Visitor;
78
David Tolnay61037c62018-01-05 16:21:03 -080079 pub fn tokens_helper<'ast, V: Visitor<'ast> + ?Sized, S: Spans>(
80 visitor: &mut V,
81 spans: &'ast S,
82 ) {
David Tolnaycc0f0372017-12-28 19:11:04 -050083 spans.visit(visitor);
84 }
85
86 pub trait Spans {
87 fn visit<'ast, V: Visitor<'ast> + ?Sized>(&'ast self, visitor: &mut V);
88 }
89
90 impl Spans for Span {
91 fn visit<'ast, V: Visitor<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
92 visitor.visit_span(self);
93 }
94 }
95
96 impl Spans for [Span; 1] {
97 fn visit<'ast, V: Visitor<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
98 visitor.visit_span(&self[0]);
99 }
100 }
101
102 impl Spans for [Span; 2] {
103 fn visit<'ast, V: Visitor<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
104 visitor.visit_span(&self[0]);
105 visitor.visit_span(&self[1]);
106 }
107 }
108
109 impl Spans for [Span; 3] {
110 fn visit<'ast, V: Visitor<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
111 visitor.visit_span(&self[0]);
112 visitor.visit_span(&self[1]);
113 visitor.visit_span(&self[2]);
114 }
115 }
116}
117
118#[cfg(feature = "visit_mut")]
119pub mod visit_mut {
120 use proc_macro2::Span;
121 use visit_mut::VisitorMut;
122
123 pub fn tokens_helper<V: VisitorMut + ?Sized, S: Spans>(visitor: &mut V, spans: &mut S) {
124 spans.visit_mut(visitor);
125 }
126
127 pub trait Spans {
128 fn visit_mut<V: VisitorMut + ?Sized>(&mut self, visitor: &mut V);
129 }
130
131 impl Spans for Span {
132 fn visit_mut<V: VisitorMut + ?Sized>(&mut self, visitor: &mut V) {
133 visitor.visit_span_mut(self);
134 }
135 }
136
137 impl Spans for [Span; 1] {
138 fn visit_mut<V: VisitorMut + ?Sized>(&mut self, visitor: &mut V) {
139 visitor.visit_span_mut(&mut self[0]);
140 }
141 }
142
143 impl Spans for [Span; 2] {
144 fn visit_mut<V: VisitorMut + ?Sized>(&mut self, visitor: &mut V) {
145 visitor.visit_span_mut(&mut self[0]);
146 visitor.visit_span_mut(&mut self[1]);
147 }
148 }
149
150 impl Spans for [Span; 3] {
151 fn visit_mut<V: VisitorMut + ?Sized>(&mut self, visitor: &mut V) {
152 visitor.visit_span_mut(&mut self[0]);
153 visitor.visit_span_mut(&mut self[1]);
154 visitor.visit_span_mut(&mut self[2]);
155 }
156 }
David Tolnayf60f4262017-12-28 19:17:58 -0500157}