blob: 436972469631f3f6970025c1f86c67973c4506a9 [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
Alex Crichtonccbb45d2017-05-23 10:58:24 -07009use std::iter::FromIterator;
10use std::slice;
11use std::vec;
Nika Layzelld73a3652017-10-24 08:57:05 -040012#[cfg(feature = "extra-traits")]
13use std::fmt::{self, Debug};
Alex Crichtonccbb45d2017-05-23 10:58:24 -070014
Nika Layzelld73a3652017-10-24 08:57:05 -040015#[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))]
Alex Crichton7b9e02f2017-05-30 15:54:33 -070016#[cfg_attr(feature = "clone-impls", derive(Clone))]
David Tolnayf2cfd722017-12-31 18:02:51 -050017pub struct Punctuated<T, P> {
18 inner: Vec<(T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070019}
20
David Tolnayf2cfd722017-12-31 18:02:51 -050021impl<T, P> Punctuated<T, P> {
22 pub fn new() -> Punctuated<T, P> {
23 Punctuated { inner: Vec::new() }
Alex Crichtonccbb45d2017-05-23 10:58:24 -070024 }
25
26 pub fn is_empty(&self) -> bool {
27 self.inner.len() == 0
28 }
29
30 pub fn len(&self) -> usize {
31 self.inner.len()
32 }
33
David Tolnayf2cfd722017-12-31 18:02:51 -050034 pub fn first(&self) -> Option<Element<&T, &P>> {
David Tolnay51382052017-12-27 13:46:21 -050035 self.inner.first().map(|&(ref t, ref d)| match *d {
David Tolnayf2cfd722017-12-31 18:02:51 -050036 Some(ref d) => Element::Punctuated(t, d),
David Tolnay51382052017-12-27 13:46:21 -050037 None => Element::End(t),
Alex Crichton0aa50e02017-07-07 20:59:03 -070038 })
39 }
40
David Tolnayf2cfd722017-12-31 18:02:51 -050041 pub fn last(&self) -> Option<Element<&T, &P>> {
David Tolnay51382052017-12-27 13:46:21 -050042 self.inner.last().map(|&(ref t, ref d)| match *d {
David Tolnayf2cfd722017-12-31 18:02:51 -050043 Some(ref d) => Element::Punctuated(t, d),
David Tolnay51382052017-12-27 13:46:21 -050044 None => Element::End(t),
Alex Crichton0aa50e02017-07-07 20:59:03 -070045 })
46 }
47
David Tolnayf2cfd722017-12-31 18:02:51 -050048 pub fn last_mut(&mut self) -> Option<Element<&mut T, &mut P>> {
David Tolnay51382052017-12-27 13:46:21 -050049 self.inner
50 .last_mut()
51 .map(|&mut (ref mut t, ref mut d)| match *d {
David Tolnayf2cfd722017-12-31 18:02:51 -050052 Some(ref mut d) => Element::Punctuated(t, d),
Alex Crichton0aa50e02017-07-07 20:59:03 -070053 None => Element::End(t),
David Tolnay51382052017-12-27 13:46:21 -050054 })
Alex Crichton0aa50e02017-07-07 20:59:03 -070055 }
56
David Tolnayf2cfd722017-12-31 18:02:51 -050057 pub fn iter(&self) -> Iter<T, P> {
David Tolnay51382052017-12-27 13:46:21 -050058 Iter {
59 inner: self.inner.iter(),
60 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 }
62
David Tolnaya0834b42018-01-01 21:30:02 -080063 pub fn iter_mut(&mut self) -> IterMut<T, P> {
64 IterMut {
65 inner: self.inner.iter_mut(),
66 }
67 }
68
David Tolnay6eff4da2018-01-01 20:27:45 -080069 pub fn elements(&self) -> Elements<T, P> {
70 Elements {
71 inner: self.inner.iter(),
72 }
73 }
74
75 pub fn elements_mut(&mut self) -> ElementsMut<T, P> {
76 ElementsMut {
David Tolnay51382052017-12-27 13:46:21 -050077 inner: self.inner.iter_mut(),
78 }
Alex Crichton164c5332017-07-06 13:18:34 -070079 }
80
David Tolnay6eff4da2018-01-01 20:27:45 -080081 pub fn into_elements(self) -> IntoElements<T, P> {
82 IntoElements {
83 inner: self.inner.into_iter(),
84 }
85 }
86
David Tolnaya0834b42018-01-01 21:30:02 -080087 pub fn push_item(&mut self, item: T) {
David Tolnaydc03aec2017-12-30 01:54:18 -050088 assert!(self.empty_or_trailing());
David Tolnaya0834b42018-01-01 21:30:02 -080089 self.inner.push((item, None));
Alex Crichtonccbb45d2017-05-23 10:58:24 -070090 }
91
David Tolnaya0834b42018-01-01 21:30:02 -080092 pub fn push_punct(&mut self, punctuation: P) {
David Tolnay660fd1f2017-12-31 01:52:57 -050093 assert!(!self.is_empty());
94 let last = self.inner.last_mut().unwrap();
95 assert!(last.1.is_none());
David Tolnayf2cfd722017-12-31 18:02:51 -050096 last.1 = Some(punctuation);
Alex Crichtonccbb45d2017-05-23 10:58:24 -070097 }
98
David Tolnayf2cfd722017-12-31 18:02:51 -050099 pub fn pop(&mut self) -> Option<Element<T, P>> {
David Tolnay660fd1f2017-12-31 01:52:57 -0500100 self.inner.pop().map(|(t, d)| Element::new(t, d))
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700101 }
102
David Tolnaya0834b42018-01-01 21:30:02 -0800103 pub fn trailing_punct(&self) -> bool {
David Tolnay61037c62018-01-05 16:21:03 -0800104 self.inner
105 .last()
106 .map(|last| last.1.is_some())
107 .unwrap_or(false)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700108 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400109
David Tolnayf2cfd722017-12-31 18:02:51 -0500110 /// Returns true if either this `Punctuated` is empty, or it has a trailing
111 /// punctuation.
David Tolnaydc03aec2017-12-30 01:54:18 -0500112 ///
David Tolnaya0834b42018-01-01 21:30:02 -0800113 /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
Michael Layzell3936ceb2017-07-08 00:28:36 -0400114 pub fn empty_or_trailing(&self) -> bool {
David Tolnay61037c62018-01-05 16:21:03 -0800115 self.inner
116 .last()
117 .map(|last| last.1.is_some())
118 .unwrap_or(true)
Michael Layzell3936ceb2017-07-08 00:28:36 -0400119 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700120}
121
David Tolnaya0834b42018-01-01 21:30:02 -0800122impl<T, P> Punctuated<T, P>
123where
124 P: Default,
125{
126 pub fn push(&mut self, item: T) {
127 if !self.empty_or_trailing() {
128 self.push_punct(Default::default());
129 }
130 self.push_item(item);
131 }
132}
133
Nika Layzelld73a3652017-10-24 08:57:05 -0400134#[cfg(feature = "extra-traits")]
David Tolnayf2cfd722017-12-31 18:02:51 -0500135impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
Nika Layzelld73a3652017-10-24 08:57:05 -0400136 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137 self.inner.fmt(f)
138 }
139}
140
David Tolnayf2cfd722017-12-31 18:02:51 -0500141impl<T, P> FromIterator<Element<T, P>> for Punctuated<T, P> {
142 fn from_iter<I: IntoIterator<Item = Element<T, P>>>(i: I) -> Self {
143 let mut ret = Punctuated::new();
Alex Crichton24f12822017-07-14 07:15:32 -0700144 ret.extend(i);
Alex Crichton954046c2017-05-30 21:49:42 -0700145 ret
146 }
147}
148
David Tolnayf2cfd722017-12-31 18:02:51 -0500149impl<T, P> Extend<Element<T, P>> for Punctuated<T, P> {
150 fn extend<I: IntoIterator<Item = Element<T, P>>>(&mut self, i: I) {
David Tolnay660fd1f2017-12-31 01:52:57 -0500151 for elem in i {
152 match elem {
David Tolnayf2cfd722017-12-31 18:02:51 -0500153 Element::Punctuated(a, b) => self.inner.push((a, Some(b))),
Alex Crichton24f12822017-07-14 07:15:32 -0700154 Element::End(a) => self.inner.push((a, None)),
155 }
156 }
157 }
158}
159
David Tolnayf2cfd722017-12-31 18:02:51 -0500160impl<T, P> IntoIterator for Punctuated<T, P> {
David Tolnay6eff4da2018-01-01 20:27:45 -0800161 type Item = T;
David Tolnayf2cfd722017-12-31 18:02:51 -0500162 type IntoIter = IntoIter<T, P>;
Alex Crichton954046c2017-05-30 21:49:42 -0700163
David Tolnaybb4ca9f2017-12-26 12:28:58 -0500164 fn into_iter(self) -> Self::IntoIter {
David Tolnay51382052017-12-27 13:46:21 -0500165 IntoIter {
166 inner: self.inner.into_iter(),
167 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700168 }
169}
170
David Tolnay6eff4da2018-01-01 20:27:45 -0800171impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
172 type Item = &'a T;
173 type IntoIter = Iter<'a, T, P>;
174
175 fn into_iter(self) -> Self::IntoIter {
176 Punctuated::iter(self)
177 }
178}
179
David Tolnaya0834b42018-01-01 21:30:02 -0800180impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
181 type Item = &'a mut T;
182 type IntoIter = IterMut<'a, T, P>;
183
184 fn into_iter(self) -> Self::IntoIter {
185 Punctuated::iter_mut(self)
186 }
187}
188
David Tolnayf2cfd722017-12-31 18:02:51 -0500189impl<T, P> Default for Punctuated<T, P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700190 fn default() -> Self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500191 Punctuated::new()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700192 }
193}
194
David Tolnay6eff4da2018-01-01 20:27:45 -0800195pub struct Elements<'a, T: 'a, P: 'a> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500196 inner: slice::Iter<'a, (T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700197}
198
David Tolnay6eff4da2018-01-01 20:27:45 -0800199impl<'a, T, P> Iterator for Elements<'a, T, P> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500200 type Item = Element<&'a T, &'a P>;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700201
David Tolnay6eff4da2018-01-01 20:27:45 -0800202 fn next(&mut self) -> Option<Self::Item> {
David Tolnay51382052017-12-27 13:46:21 -0500203 self.inner.next().map(|pair| match pair.1 {
David Tolnayf2cfd722017-12-31 18:02:51 -0500204 Some(ref p) => Element::Punctuated(&pair.0, p),
David Tolnay51382052017-12-27 13:46:21 -0500205 None => Element::End(&pair.0),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700206 })
207 }
208}
209
David Tolnay6eff4da2018-01-01 20:27:45 -0800210pub struct ElementsMut<'a, T: 'a, P: 'a> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500211 inner: slice::IterMut<'a, (T, Option<P>)>,
Alex Crichton164c5332017-07-06 13:18:34 -0700212}
213
David Tolnay6eff4da2018-01-01 20:27:45 -0800214impl<'a, T, P> Iterator for ElementsMut<'a, T, P> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500215 type Item = Element<&'a mut T, &'a mut P>;
Alex Crichton164c5332017-07-06 13:18:34 -0700216
David Tolnay6eff4da2018-01-01 20:27:45 -0800217 fn next(&mut self) -> Option<Self::Item> {
David Tolnay51382052017-12-27 13:46:21 -0500218 self.inner.next().map(|pair| match pair.1 {
David Tolnayf2cfd722017-12-31 18:02:51 -0500219 Some(ref mut p) => Element::Punctuated(&mut pair.0, p),
David Tolnay51382052017-12-27 13:46:21 -0500220 None => Element::End(&mut pair.0),
Alex Crichton164c5332017-07-06 13:18:34 -0700221 })
222 }
223}
224
David Tolnay6eff4da2018-01-01 20:27:45 -0800225pub struct IntoElements<T, P> {
226 inner: vec::IntoIter<(T, Option<P>)>,
227}
228
229impl<T, P> Iterator for IntoElements<T, P> {
230 type Item = Element<T, P>;
231
232 fn next(&mut self) -> Option<Self::Item> {
233 self.inner.next().map(|pair| match pair.1 {
234 Some(p) => Element::Punctuated(pair.0, p),
235 None => Element::End(pair.0),
236 })
237 }
238}
239
David Tolnayf2cfd722017-12-31 18:02:51 -0500240pub struct IntoIter<T, P> {
241 inner: vec::IntoIter<(T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700242}
243
David Tolnayf2cfd722017-12-31 18:02:51 -0500244impl<T, P> Iterator for IntoIter<T, P> {
David Tolnay6eff4da2018-01-01 20:27:45 -0800245 type Item = T;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700246
David Tolnay6eff4da2018-01-01 20:27:45 -0800247 fn next(&mut self) -> Option<Self::Item> {
248 self.inner.next().map(|pair| pair.0)
249 }
250}
251
252pub struct Iter<'a, T: 'a, P: 'a> {
253 inner: slice::Iter<'a, (T, Option<P>)>,
254}
255
256impl<'a, T, P> Iterator for Iter<'a, T, P> {
257 type Item = &'a T;
258
259 fn next(&mut self) -> Option<Self::Item> {
260 self.inner.next().map(|pair| &pair.0)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700261 }
262}
263
David Tolnaya0834b42018-01-01 21:30:02 -0800264pub struct IterMut<'a, T: 'a, P: 'a> {
265 inner: slice::IterMut<'a, (T, Option<P>)>,
266}
267
268impl<'a, T, P> Iterator for IterMut<'a, T, P> {
269 type Item = &'a mut T;
270
271 fn next(&mut self) -> Option<Self::Item> {
272 self.inner.next().map(|pair| &mut pair.0)
273 }
274}
275
David Tolnayf2cfd722017-12-31 18:02:51 -0500276pub enum Element<T, P> {
277 Punctuated(T, P),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700278 End(T),
279}
280
David Tolnayf2cfd722017-12-31 18:02:51 -0500281impl<T, P> Element<T, P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700282 pub fn into_item(self) -> T {
283 match self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500284 Element::Punctuated(t, _) | Element::End(t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700285 }
286 }
287
288 pub fn item(&self) -> &T {
289 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500290 Element::Punctuated(ref t, _) | Element::End(ref t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700291 }
292 }
293
294 pub fn item_mut(&mut self) -> &mut T {
295 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500296 Element::Punctuated(ref mut t, _) | Element::End(ref mut t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700297 }
298 }
299
David Tolnayf2cfd722017-12-31 18:02:51 -0500300 pub fn punct(&self) -> Option<&P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700301 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500302 Element::Punctuated(_, ref d) => Some(d),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700303 Element::End(_) => None,
304 }
305 }
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400306
David Tolnayf2cfd722017-12-31 18:02:51 -0500307 pub fn new(t: T, d: Option<P>) -> Self {
David Tolnay660fd1f2017-12-31 01:52:57 -0500308 match d {
David Tolnayf2cfd722017-12-31 18:02:51 -0500309 Some(d) => Element::Punctuated(t, d),
David Tolnay660fd1f2017-12-31 01:52:57 -0500310 None => Element::End(t),
311 }
312 }
313
David Tolnayf2cfd722017-12-31 18:02:51 -0500314 pub fn into_tuple(self) -> (T, Option<P>) {
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400315 match self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500316 Element::Punctuated(t, d) => (t, Some(d)),
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400317 Element::End(t) => (t, None),
318 }
319 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700320}
321
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700322#[cfg(feature = "parsing")]
323mod parsing {
David Tolnayf2cfd722017-12-31 18:02:51 -0500324 use super::Punctuated;
David Tolnayc5ab8c62017-12-26 16:43:39 -0500325 use synom::Synom;
326 use cursor::Cursor;
David Tolnay203557a2017-12-27 23:59:33 -0500327 use parse_error;
328 use synom::PResult;
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700329
David Tolnayf2cfd722017-12-31 18:02:51 -0500330 impl<T, P> Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500331 where
332 T: Synom,
David Tolnayf2cfd722017-12-31 18:02:51 -0500333 P: Synom,
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700334 {
David Tolnay51382052017-12-27 13:46:21 -0500335 pub fn parse_separated(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700336 Self::parse(input, T::parse, false)
337 }
338
David Tolnay51382052017-12-27 13:46:21 -0500339 pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700340 Self::parse_separated_nonempty_with(input, T::parse)
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700341 }
342
David Tolnay51382052017-12-27 13:46:21 -0500343 pub fn parse_terminated(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700344 Self::parse_terminated_with(input, T::parse)
345 }
Nika Layzellb49a9e52017-12-05 13:31:52 -0500346
David Tolnay51382052017-12-27 13:46:21 -0500347 pub fn parse_terminated_nonempty(input: Cursor) -> PResult<Self> {
Nika Layzellb49a9e52017-12-05 13:31:52 -0500348 Self::parse_terminated_nonempty_with(input, T::parse)
349 }
Alex Crichton954046c2017-05-30 21:49:42 -0700350 }
351
David Tolnayf2cfd722017-12-31 18:02:51 -0500352 impl<T, P> Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500353 where
David Tolnayf2cfd722017-12-31 18:02:51 -0500354 P: Synom,
Alex Crichton954046c2017-05-30 21:49:42 -0700355 {
David Tolnaydc03aec2017-12-30 01:54:18 -0500356 pub fn parse_separated_with(
357 input: Cursor,
358 parse: fn(Cursor) -> PResult<T>,
359 ) -> PResult<Self> {
360 Self::parse(input, parse, false)
361 }
362
Alex Crichton954046c2017-05-30 21:49:42 -0700363 pub fn parse_separated_nonempty_with(
David Tolnay51382052017-12-27 13:46:21 -0500364 input: Cursor,
365 parse: fn(Cursor) -> PResult<T>,
366 ) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700367 match Self::parse(input, parse, false) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500368 Ok((ref b, _)) if b.is_empty() => parse_error(),
Alex Crichton954046c2017-05-30 21:49:42 -0700369 other => other,
370 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700371 }
372
Alex Crichton954046c2017-05-30 21:49:42 -0700373 pub fn parse_terminated_with(
David Tolnay51382052017-12-27 13:46:21 -0500374 input: Cursor,
375 parse: fn(Cursor) -> PResult<T>,
376 ) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700377 Self::parse(input, parse, true)
378 }
379
Nika Layzellb49a9e52017-12-05 13:31:52 -0500380 pub fn parse_terminated_nonempty_with(
David Tolnay51382052017-12-27 13:46:21 -0500381 input: Cursor,
382 parse: fn(Cursor) -> PResult<T>,
383 ) -> PResult<Self> {
Nika Layzellb49a9e52017-12-05 13:31:52 -0500384 match Self::parse(input, parse, true) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500385 Ok((ref b, _)) if b.is_empty() => parse_error(),
Nika Layzellb49a9e52017-12-05 13:31:52 -0500386 other => other,
387 }
388 }
389
David Tolnay51382052017-12-27 13:46:21 -0500390 fn parse(
391 mut input: Cursor,
392 parse: fn(Cursor) -> PResult<T>,
393 terminated: bool,
394 ) -> PResult<Self> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500395 let mut res = Punctuated::new();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700396
397 // get the first element
Alex Crichton954046c2017-05-30 21:49:42 -0700398 match parse(input) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500399 Err(_) => Ok((res, input)),
400 Ok((o, i)) => {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400401 if i == input {
Michael Layzell760fd662017-05-31 22:46:05 -0400402 return parse_error();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700403 }
404 input = i;
David Tolnaya0834b42018-01-01 21:30:02 -0800405 res.push_item(o);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700406
407 // get the separator first
David Tolnayf2cfd722017-12-31 18:02:51 -0500408 while let Ok((s, i2)) = P::parse(input) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400409 if i2 == input {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700410 break;
411 }
412
413 // get the element next
David Tolnayf4aa6b42017-12-31 16:40:33 -0500414 if let Ok((o3, i3)) = parse(i2) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400415 if i3 == i2 {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700416 break;
417 }
David Tolnaya0834b42018-01-01 21:30:02 -0800418 res.push_punct(s);
419 res.push_item(o3);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700420 input = i3;
421 } else {
422 break;
423 }
424 }
425 if terminated {
David Tolnayf2cfd722017-12-31 18:02:51 -0500426 if let Ok((sep, after)) = P::parse(input) {
David Tolnaya0834b42018-01-01 21:30:02 -0800427 res.push_punct(sep);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700428 input = after;
429 }
430 }
David Tolnayf4aa6b42017-12-31 16:40:33 -0500431 Ok((res, input))
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700432 }
433 }
434 }
435 }
436}
437
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700438#[cfg(feature = "printing")]
439mod printing {
440 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500441 use quote::{ToTokens, Tokens};
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700442
David Tolnayf2cfd722017-12-31 18:02:51 -0500443 impl<T, P> ToTokens for Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500444 where
445 T: ToTokens,
David Tolnayf2cfd722017-12-31 18:02:51 -0500446 P: ToTokens,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700447 {
448 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaya0834b42018-01-01 21:30:02 -0800449 tokens.append_all(self.elements())
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700450 }
451 }
452
David Tolnayf2cfd722017-12-31 18:02:51 -0500453 impl<T, P> ToTokens for Element<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500454 where
455 T: ToTokens,
David Tolnayf2cfd722017-12-31 18:02:51 -0500456 P: ToTokens,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700457 {
458 fn to_tokens(&self, tokens: &mut Tokens) {
459 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500460 Element::Punctuated(ref a, ref b) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700461 a.to_tokens(tokens);
462 b.to_tokens(tokens);
463 }
464 Element::End(ref a) => a.to_tokens(tokens),
465 }
466 }
467 }
468}