blob: e8e6bd75c478c97acf2ba2af985e06d694bd3678 [file] [log] [blame]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001use std::iter::FromIterator;
2use std::slice;
3use std::vec;
Nika Layzelld73a3652017-10-24 08:57:05 -04004#[cfg(feature = "extra-traits")]
5use std::fmt::{self, Debug};
Alex Crichtonccbb45d2017-05-23 10:58:24 -07006
Nika Layzelld73a3652017-10-24 08:57:05 -04007#[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))]
Alex Crichton7b9e02f2017-05-30 15:54:33 -07008#[cfg_attr(feature = "clone-impls", derive(Clone))]
David Tolnayf2cfd722017-12-31 18:02:51 -05009pub struct Punctuated<T, P> {
10 inner: Vec<(T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070011}
12
David Tolnayf2cfd722017-12-31 18:02:51 -050013impl<T, P> Punctuated<T, P> {
14 pub fn new() -> Punctuated<T, P> {
15 Punctuated { inner: Vec::new() }
Alex Crichtonccbb45d2017-05-23 10:58:24 -070016 }
17
18 pub fn is_empty(&self) -> bool {
19 self.inner.len() == 0
20 }
21
22 pub fn len(&self) -> usize {
23 self.inner.len()
24 }
25
David Tolnayf2cfd722017-12-31 18:02:51 -050026 pub fn first(&self) -> Option<Element<&T, &P>> {
David Tolnay51382052017-12-27 13:46:21 -050027 self.inner.first().map(|&(ref t, ref d)| match *d {
David Tolnayf2cfd722017-12-31 18:02:51 -050028 Some(ref d) => Element::Punctuated(t, d),
David Tolnay51382052017-12-27 13:46:21 -050029 None => Element::End(t),
Alex Crichton0aa50e02017-07-07 20:59:03 -070030 })
31 }
32
David Tolnayf2cfd722017-12-31 18:02:51 -050033 pub fn last(&self) -> Option<Element<&T, &P>> {
David Tolnay51382052017-12-27 13:46:21 -050034 self.inner.last().map(|&(ref t, ref d)| match *d {
David Tolnayf2cfd722017-12-31 18:02:51 -050035 Some(ref d) => Element::Punctuated(t, d),
David Tolnay51382052017-12-27 13:46:21 -050036 None => Element::End(t),
Alex Crichton0aa50e02017-07-07 20:59:03 -070037 })
38 }
39
David Tolnayf2cfd722017-12-31 18:02:51 -050040 pub fn last_mut(&mut self) -> Option<Element<&mut T, &mut P>> {
David Tolnay51382052017-12-27 13:46:21 -050041 self.inner
42 .last_mut()
43 .map(|&mut (ref mut t, ref mut d)| match *d {
David Tolnayf2cfd722017-12-31 18:02:51 -050044 Some(ref mut d) => Element::Punctuated(t, d),
Alex Crichton0aa50e02017-07-07 20:59:03 -070045 None => Element::End(t),
David Tolnay51382052017-12-27 13:46:21 -050046 })
Alex Crichton0aa50e02017-07-07 20:59:03 -070047 }
48
David Tolnayf2cfd722017-12-31 18:02:51 -050049 pub fn iter(&self) -> Iter<T, P> {
David Tolnay51382052017-12-27 13:46:21 -050050 Iter {
51 inner: self.inner.iter(),
52 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -070053 }
54
David Tolnay6eff4da2018-01-01 20:27:45 -080055 pub fn elements(&self) -> Elements<T, P> {
56 Elements {
57 inner: self.inner.iter(),
58 }
59 }
60
61 pub fn elements_mut(&mut self) -> ElementsMut<T, P> {
62 ElementsMut {
David Tolnay51382052017-12-27 13:46:21 -050063 inner: self.inner.iter_mut(),
64 }
Alex Crichton164c5332017-07-06 13:18:34 -070065 }
66
David Tolnay6eff4da2018-01-01 20:27:45 -080067 pub fn into_elements(self) -> IntoElements<T, P> {
68 IntoElements {
69 inner: self.inner.into_iter(),
70 }
71 }
72
David Tolnay660fd1f2017-12-31 01:52:57 -050073 pub fn push(&mut self, token: T) {
David Tolnaydc03aec2017-12-30 01:54:18 -050074 assert!(self.empty_or_trailing());
Alex Crichtonccbb45d2017-05-23 10:58:24 -070075 self.inner.push((token, None));
76 }
77
David Tolnayf2cfd722017-12-31 18:02:51 -050078 pub fn push_trailing(&mut self, punctuation: P) {
David Tolnay660fd1f2017-12-31 01:52:57 -050079 assert!(!self.is_empty());
80 let last = self.inner.last_mut().unwrap();
81 assert!(last.1.is_none());
David Tolnayf2cfd722017-12-31 18:02:51 -050082 last.1 = Some(punctuation);
Alex Crichtonccbb45d2017-05-23 10:58:24 -070083 }
84
David Tolnayf2cfd722017-12-31 18:02:51 -050085 pub fn pop(&mut self) -> Option<Element<T, P>> {
David Tolnay660fd1f2017-12-31 01:52:57 -050086 self.inner.pop().map(|(t, d)| Element::new(t, d))
Alex Crichtonccbb45d2017-05-23 10:58:24 -070087 }
88
89 pub fn trailing_delim(&self) -> bool {
David Tolnay660fd1f2017-12-31 01:52:57 -050090 self.inner.last().map(|last| last.1.is_some()).unwrap_or(false)
Alex Crichtonccbb45d2017-05-23 10:58:24 -070091 }
Michael Layzell3936ceb2017-07-08 00:28:36 -040092
David Tolnayf2cfd722017-12-31 18:02:51 -050093 /// Returns true if either this `Punctuated` is empty, or it has a trailing
94 /// punctuation.
David Tolnaydc03aec2017-12-30 01:54:18 -050095 ///
David Tolnayf2cfd722017-12-31 18:02:51 -050096 /// Equivalent to `punctuated.is_empty() || punctuated.trailing_delim()`.
Michael Layzell3936ceb2017-07-08 00:28:36 -040097 pub fn empty_or_trailing(&self) -> bool {
David Tolnay660fd1f2017-12-31 01:52:57 -050098 self.inner.last().map(|last| last.1.is_some()).unwrap_or(true)
Michael Layzell3936ceb2017-07-08 00:28:36 -040099 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700100}
101
Nika Layzelld73a3652017-10-24 08:57:05 -0400102#[cfg(feature = "extra-traits")]
David Tolnayf2cfd722017-12-31 18:02:51 -0500103impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
Nika Layzelld73a3652017-10-24 08:57:05 -0400104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 self.inner.fmt(f)
106 }
107}
108
David Tolnayf2cfd722017-12-31 18:02:51 -0500109impl<T, P> FromIterator<Element<T, P>> for Punctuated<T, P> {
110 fn from_iter<I: IntoIterator<Item = Element<T, P>>>(i: I) -> Self {
111 let mut ret = Punctuated::new();
Alex Crichton24f12822017-07-14 07:15:32 -0700112 ret.extend(i);
Alex Crichton954046c2017-05-30 21:49:42 -0700113 ret
114 }
115}
116
David Tolnayf2cfd722017-12-31 18:02:51 -0500117impl<T, P> Extend<Element<T, P>> for Punctuated<T, P> {
118 fn extend<I: IntoIterator<Item = Element<T, P>>>(&mut self, i: I) {
David Tolnay660fd1f2017-12-31 01:52:57 -0500119 for elem in i {
120 match elem {
David Tolnayf2cfd722017-12-31 18:02:51 -0500121 Element::Punctuated(a, b) => self.inner.push((a, Some(b))),
Alex Crichton24f12822017-07-14 07:15:32 -0700122 Element::End(a) => self.inner.push((a, None)),
123 }
124 }
125 }
126}
127
David Tolnayf2cfd722017-12-31 18:02:51 -0500128impl<T, P> IntoIterator for Punctuated<T, P> {
David Tolnay6eff4da2018-01-01 20:27:45 -0800129 type Item = T;
David Tolnayf2cfd722017-12-31 18:02:51 -0500130 type IntoIter = IntoIter<T, P>;
Alex Crichton954046c2017-05-30 21:49:42 -0700131
David Tolnaybb4ca9f2017-12-26 12:28:58 -0500132 fn into_iter(self) -> Self::IntoIter {
David Tolnay51382052017-12-27 13:46:21 -0500133 IntoIter {
134 inner: self.inner.into_iter(),
135 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700136 }
137}
138
David Tolnay6eff4da2018-01-01 20:27:45 -0800139impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
140 type Item = &'a T;
141 type IntoIter = Iter<'a, T, P>;
142
143 fn into_iter(self) -> Self::IntoIter {
144 Punctuated::iter(self)
145 }
146}
147
David Tolnayf2cfd722017-12-31 18:02:51 -0500148impl<T, P> Default for Punctuated<T, P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700149 fn default() -> Self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500150 Punctuated::new()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700151 }
152}
153
David Tolnay6eff4da2018-01-01 20:27:45 -0800154pub struct Elements<'a, T: 'a, P: 'a> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500155 inner: slice::Iter<'a, (T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700156}
157
David Tolnay6eff4da2018-01-01 20:27:45 -0800158impl<'a, T, P> Iterator for Elements<'a, T, P> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500159 type Item = Element<&'a T, &'a P>;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700160
David Tolnay6eff4da2018-01-01 20:27:45 -0800161 fn next(&mut self) -> Option<Self::Item> {
David Tolnay51382052017-12-27 13:46:21 -0500162 self.inner.next().map(|pair| match pair.1 {
David Tolnayf2cfd722017-12-31 18:02:51 -0500163 Some(ref p) => Element::Punctuated(&pair.0, p),
David Tolnay51382052017-12-27 13:46:21 -0500164 None => Element::End(&pair.0),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700165 })
166 }
167}
168
David Tolnay6eff4da2018-01-01 20:27:45 -0800169pub struct ElementsMut<'a, T: 'a, P: 'a> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500170 inner: slice::IterMut<'a, (T, Option<P>)>,
Alex Crichton164c5332017-07-06 13:18:34 -0700171}
172
David Tolnay6eff4da2018-01-01 20:27:45 -0800173impl<'a, T, P> Iterator for ElementsMut<'a, T, P> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500174 type Item = Element<&'a mut T, &'a mut P>;
Alex Crichton164c5332017-07-06 13:18:34 -0700175
David Tolnay6eff4da2018-01-01 20:27:45 -0800176 fn next(&mut self) -> Option<Self::Item> {
David Tolnay51382052017-12-27 13:46:21 -0500177 self.inner.next().map(|pair| match pair.1 {
David Tolnayf2cfd722017-12-31 18:02:51 -0500178 Some(ref mut p) => Element::Punctuated(&mut pair.0, p),
David Tolnay51382052017-12-27 13:46:21 -0500179 None => Element::End(&mut pair.0),
Alex Crichton164c5332017-07-06 13:18:34 -0700180 })
181 }
182}
183
David Tolnay6eff4da2018-01-01 20:27:45 -0800184pub struct IntoElements<T, P> {
185 inner: vec::IntoIter<(T, Option<P>)>,
186}
187
188impl<T, P> Iterator for IntoElements<T, P> {
189 type Item = Element<T, P>;
190
191 fn next(&mut self) -> Option<Self::Item> {
192 self.inner.next().map(|pair| match pair.1 {
193 Some(p) => Element::Punctuated(pair.0, p),
194 None => Element::End(pair.0),
195 })
196 }
197}
198
David Tolnayf2cfd722017-12-31 18:02:51 -0500199pub struct IntoIter<T, P> {
200 inner: vec::IntoIter<(T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700201}
202
David Tolnayf2cfd722017-12-31 18:02:51 -0500203impl<T, P> Iterator for IntoIter<T, P> {
David Tolnay6eff4da2018-01-01 20:27:45 -0800204 type Item = T;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700205
David Tolnay6eff4da2018-01-01 20:27:45 -0800206 fn next(&mut self) -> Option<Self::Item> {
207 self.inner.next().map(|pair| pair.0)
208 }
209}
210
211pub struct Iter<'a, T: 'a, P: 'a> {
212 inner: slice::Iter<'a, (T, Option<P>)>,
213}
214
215impl<'a, T, P> Iterator for Iter<'a, T, P> {
216 type Item = &'a T;
217
218 fn next(&mut self) -> Option<Self::Item> {
219 self.inner.next().map(|pair| &pair.0)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700220 }
221}
222
David Tolnayf2cfd722017-12-31 18:02:51 -0500223pub enum Element<T, P> {
224 Punctuated(T, P),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700225 End(T),
226}
227
David Tolnayf2cfd722017-12-31 18:02:51 -0500228impl<T, P> Element<T, P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700229 pub fn into_item(self) -> T {
230 match self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500231 Element::Punctuated(t, _) | Element::End(t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700232 }
233 }
234
235 pub fn item(&self) -> &T {
236 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500237 Element::Punctuated(ref t, _) | Element::End(ref t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700238 }
239 }
240
241 pub fn item_mut(&mut self) -> &mut T {
242 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500243 Element::Punctuated(ref mut t, _) | Element::End(ref mut t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700244 }
245 }
246
David Tolnayf2cfd722017-12-31 18:02:51 -0500247 pub fn punct(&self) -> Option<&P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700248 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500249 Element::Punctuated(_, ref d) => Some(d),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700250 Element::End(_) => None,
251 }
252 }
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400253
David Tolnayf2cfd722017-12-31 18:02:51 -0500254 pub fn new(t: T, d: Option<P>) -> Self {
David Tolnay660fd1f2017-12-31 01:52:57 -0500255 match d {
David Tolnayf2cfd722017-12-31 18:02:51 -0500256 Some(d) => Element::Punctuated(t, d),
David Tolnay660fd1f2017-12-31 01:52:57 -0500257 None => Element::End(t),
258 }
259 }
260
David Tolnayf2cfd722017-12-31 18:02:51 -0500261 pub fn into_tuple(self) -> (T, Option<P>) {
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400262 match self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500263 Element::Punctuated(t, d) => (t, Some(d)),
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400264 Element::End(t) => (t, None),
265 }
266 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700267}
268
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700269#[cfg(feature = "parsing")]
270mod parsing {
David Tolnayf2cfd722017-12-31 18:02:51 -0500271 use super::Punctuated;
David Tolnayc5ab8c62017-12-26 16:43:39 -0500272 use synom::Synom;
273 use cursor::Cursor;
David Tolnay203557a2017-12-27 23:59:33 -0500274 use parse_error;
275 use synom::PResult;
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700276
David Tolnayf2cfd722017-12-31 18:02:51 -0500277 impl<T, P> Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500278 where
279 T: Synom,
David Tolnayf2cfd722017-12-31 18:02:51 -0500280 P: Synom,
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700281 {
David Tolnay51382052017-12-27 13:46:21 -0500282 pub fn parse_separated(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700283 Self::parse(input, T::parse, false)
284 }
285
David Tolnay51382052017-12-27 13:46:21 -0500286 pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700287 Self::parse_separated_nonempty_with(input, T::parse)
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700288 }
289
David Tolnay51382052017-12-27 13:46:21 -0500290 pub fn parse_terminated(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700291 Self::parse_terminated_with(input, T::parse)
292 }
Nika Layzellb49a9e52017-12-05 13:31:52 -0500293
David Tolnay51382052017-12-27 13:46:21 -0500294 pub fn parse_terminated_nonempty(input: Cursor) -> PResult<Self> {
Nika Layzellb49a9e52017-12-05 13:31:52 -0500295 Self::parse_terminated_nonempty_with(input, T::parse)
296 }
Alex Crichton954046c2017-05-30 21:49:42 -0700297 }
298
David Tolnayf2cfd722017-12-31 18:02:51 -0500299 impl<T, P> Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500300 where
David Tolnayf2cfd722017-12-31 18:02:51 -0500301 P: Synom,
Alex Crichton954046c2017-05-30 21:49:42 -0700302 {
David Tolnaydc03aec2017-12-30 01:54:18 -0500303 pub fn parse_separated_with(
304 input: Cursor,
305 parse: fn(Cursor) -> PResult<T>,
306 ) -> PResult<Self> {
307 Self::parse(input, parse, false)
308 }
309
Alex Crichton954046c2017-05-30 21:49:42 -0700310 pub fn parse_separated_nonempty_with(
David Tolnay51382052017-12-27 13:46:21 -0500311 input: Cursor,
312 parse: fn(Cursor) -> PResult<T>,
313 ) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700314 match Self::parse(input, parse, false) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500315 Ok((ref b, _)) if b.is_empty() => parse_error(),
Alex Crichton954046c2017-05-30 21:49:42 -0700316 other => other,
317 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700318 }
319
Alex Crichton954046c2017-05-30 21:49:42 -0700320 pub fn parse_terminated_with(
David Tolnay51382052017-12-27 13:46:21 -0500321 input: Cursor,
322 parse: fn(Cursor) -> PResult<T>,
323 ) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700324 Self::parse(input, parse, true)
325 }
326
Nika Layzellb49a9e52017-12-05 13:31:52 -0500327 pub fn parse_terminated_nonempty_with(
David Tolnay51382052017-12-27 13:46:21 -0500328 input: Cursor,
329 parse: fn(Cursor) -> PResult<T>,
330 ) -> PResult<Self> {
Nika Layzellb49a9e52017-12-05 13:31:52 -0500331 match Self::parse(input, parse, true) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500332 Ok((ref b, _)) if b.is_empty() => parse_error(),
Nika Layzellb49a9e52017-12-05 13:31:52 -0500333 other => other,
334 }
335 }
336
David Tolnay51382052017-12-27 13:46:21 -0500337 fn parse(
338 mut input: Cursor,
339 parse: fn(Cursor) -> PResult<T>,
340 terminated: bool,
341 ) -> PResult<Self> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500342 let mut res = Punctuated::new();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700343
344 // get the first element
Alex Crichton954046c2017-05-30 21:49:42 -0700345 match parse(input) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500346 Err(_) => Ok((res, input)),
347 Ok((o, i)) => {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400348 if i == input {
Michael Layzell760fd662017-05-31 22:46:05 -0400349 return parse_error();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700350 }
351 input = i;
David Tolnay660fd1f2017-12-31 01:52:57 -0500352 res.push(o);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700353
354 // get the separator first
David Tolnayf2cfd722017-12-31 18:02:51 -0500355 while let Ok((s, i2)) = P::parse(input) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400356 if i2 == input {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700357 break;
358 }
359
360 // get the element next
David Tolnayf4aa6b42017-12-31 16:40:33 -0500361 if let Ok((o3, i3)) = parse(i2) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400362 if i3 == i2 {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700363 break;
364 }
David Tolnay660fd1f2017-12-31 01:52:57 -0500365 res.push_trailing(s);
366 res.push(o3);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700367 input = i3;
368 } else {
369 break;
370 }
371 }
372 if terminated {
David Tolnayf2cfd722017-12-31 18:02:51 -0500373 if let Ok((sep, after)) = P::parse(input) {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700374 res.push_trailing(sep);
375 input = after;
376 }
377 }
David Tolnayf4aa6b42017-12-31 16:40:33 -0500378 Ok((res, input))
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700379 }
380 }
381 }
382 }
383}
384
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700385#[cfg(feature = "printing")]
386mod printing {
387 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500388 use quote::{ToTokens, Tokens};
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700389
David Tolnayf2cfd722017-12-31 18:02:51 -0500390 impl<T, P> ToTokens for Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500391 where
392 T: ToTokens,
David Tolnayf2cfd722017-12-31 18:02:51 -0500393 P: ToTokens,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700394 {
395 fn to_tokens(&self, tokens: &mut Tokens) {
396 tokens.append_all(self.iter())
397 }
398 }
399
David Tolnayf2cfd722017-12-31 18:02:51 -0500400 impl<T, P> ToTokens for Element<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500401 where
402 T: ToTokens,
David Tolnayf2cfd722017-12-31 18:02:51 -0500403 P: ToTokens,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700404 {
405 fn to_tokens(&self, tokens: &mut Tokens) {
406 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500407 Element::Punctuated(ref a, ref b) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700408 a.to_tokens(tokens);
409 b.to_tokens(tokens);
410 }
411 Element::End(ref a) => a.to_tokens(tokens),
412 }
413 }
414 }
415}