blob: ccf75970c1da574d921c8d28cd475f3c1e07e834 [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 Tolnaya0834b42018-01-01 21:30:02 -080055 pub fn iter_mut(&mut self) -> IterMut<T, P> {
56 IterMut {
57 inner: self.inner.iter_mut(),
58 }
59 }
60
David Tolnay6eff4da2018-01-01 20:27:45 -080061 pub fn elements(&self) -> Elements<T, P> {
62 Elements {
63 inner: self.inner.iter(),
64 }
65 }
66
67 pub fn elements_mut(&mut self) -> ElementsMut<T, P> {
68 ElementsMut {
David Tolnay51382052017-12-27 13:46:21 -050069 inner: self.inner.iter_mut(),
70 }
Alex Crichton164c5332017-07-06 13:18:34 -070071 }
72
David Tolnay6eff4da2018-01-01 20:27:45 -080073 pub fn into_elements(self) -> IntoElements<T, P> {
74 IntoElements {
75 inner: self.inner.into_iter(),
76 }
77 }
78
David Tolnaya0834b42018-01-01 21:30:02 -080079 pub fn push_item(&mut self, item: T) {
David Tolnaydc03aec2017-12-30 01:54:18 -050080 assert!(self.empty_or_trailing());
David Tolnaya0834b42018-01-01 21:30:02 -080081 self.inner.push((item, None));
Alex Crichtonccbb45d2017-05-23 10:58:24 -070082 }
83
David Tolnaya0834b42018-01-01 21:30:02 -080084 pub fn push_punct(&mut self, punctuation: P) {
David Tolnay660fd1f2017-12-31 01:52:57 -050085 assert!(!self.is_empty());
86 let last = self.inner.last_mut().unwrap();
87 assert!(last.1.is_none());
David Tolnayf2cfd722017-12-31 18:02:51 -050088 last.1 = Some(punctuation);
Alex Crichtonccbb45d2017-05-23 10:58:24 -070089 }
90
David Tolnayf2cfd722017-12-31 18:02:51 -050091 pub fn pop(&mut self) -> Option<Element<T, P>> {
David Tolnay660fd1f2017-12-31 01:52:57 -050092 self.inner.pop().map(|(t, d)| Element::new(t, d))
Alex Crichtonccbb45d2017-05-23 10:58:24 -070093 }
94
David Tolnaya0834b42018-01-01 21:30:02 -080095 pub fn trailing_punct(&self) -> bool {
David Tolnay61037c62018-01-05 16:21:03 -080096 self.inner
97 .last()
98 .map(|last| last.1.is_some())
99 .unwrap_or(false)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700100 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400101
David Tolnayf2cfd722017-12-31 18:02:51 -0500102 /// Returns true if either this `Punctuated` is empty, or it has a trailing
103 /// punctuation.
David Tolnaydc03aec2017-12-30 01:54:18 -0500104 ///
David Tolnaya0834b42018-01-01 21:30:02 -0800105 /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
Michael Layzell3936ceb2017-07-08 00:28:36 -0400106 pub fn empty_or_trailing(&self) -> bool {
David Tolnay61037c62018-01-05 16:21:03 -0800107 self.inner
108 .last()
109 .map(|last| last.1.is_some())
110 .unwrap_or(true)
Michael Layzell3936ceb2017-07-08 00:28:36 -0400111 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700112}
113
David Tolnaya0834b42018-01-01 21:30:02 -0800114impl<T, P> Punctuated<T, P>
115where
116 P: Default,
117{
118 pub fn push(&mut self, item: T) {
119 if !self.empty_or_trailing() {
120 self.push_punct(Default::default());
121 }
122 self.push_item(item);
123 }
124}
125
Nika Layzelld73a3652017-10-24 08:57:05 -0400126#[cfg(feature = "extra-traits")]
David Tolnayf2cfd722017-12-31 18:02:51 -0500127impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
Nika Layzelld73a3652017-10-24 08:57:05 -0400128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129 self.inner.fmt(f)
130 }
131}
132
David Tolnayf2cfd722017-12-31 18:02:51 -0500133impl<T, P> FromIterator<Element<T, P>> for Punctuated<T, P> {
134 fn from_iter<I: IntoIterator<Item = Element<T, P>>>(i: I) -> Self {
135 let mut ret = Punctuated::new();
Alex Crichton24f12822017-07-14 07:15:32 -0700136 ret.extend(i);
Alex Crichton954046c2017-05-30 21:49:42 -0700137 ret
138 }
139}
140
David Tolnayf2cfd722017-12-31 18:02:51 -0500141impl<T, P> Extend<Element<T, P>> for Punctuated<T, P> {
142 fn extend<I: IntoIterator<Item = Element<T, P>>>(&mut self, i: I) {
David Tolnay660fd1f2017-12-31 01:52:57 -0500143 for elem in i {
144 match elem {
David Tolnayf2cfd722017-12-31 18:02:51 -0500145 Element::Punctuated(a, b) => self.inner.push((a, Some(b))),
Alex Crichton24f12822017-07-14 07:15:32 -0700146 Element::End(a) => self.inner.push((a, None)),
147 }
148 }
149 }
150}
151
David Tolnayf2cfd722017-12-31 18:02:51 -0500152impl<T, P> IntoIterator for Punctuated<T, P> {
David Tolnay6eff4da2018-01-01 20:27:45 -0800153 type Item = T;
David Tolnayf2cfd722017-12-31 18:02:51 -0500154 type IntoIter = IntoIter<T, P>;
Alex Crichton954046c2017-05-30 21:49:42 -0700155
David Tolnaybb4ca9f2017-12-26 12:28:58 -0500156 fn into_iter(self) -> Self::IntoIter {
David Tolnay51382052017-12-27 13:46:21 -0500157 IntoIter {
158 inner: self.inner.into_iter(),
159 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700160 }
161}
162
David Tolnay6eff4da2018-01-01 20:27:45 -0800163impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
164 type Item = &'a T;
165 type IntoIter = Iter<'a, T, P>;
166
167 fn into_iter(self) -> Self::IntoIter {
168 Punctuated::iter(self)
169 }
170}
171
David Tolnaya0834b42018-01-01 21:30:02 -0800172impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
173 type Item = &'a mut T;
174 type IntoIter = IterMut<'a, T, P>;
175
176 fn into_iter(self) -> Self::IntoIter {
177 Punctuated::iter_mut(self)
178 }
179}
180
David Tolnayf2cfd722017-12-31 18:02:51 -0500181impl<T, P> Default for Punctuated<T, P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700182 fn default() -> Self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500183 Punctuated::new()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700184 }
185}
186
David Tolnay6eff4da2018-01-01 20:27:45 -0800187pub struct Elements<'a, T: 'a, P: 'a> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500188 inner: slice::Iter<'a, (T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700189}
190
David Tolnay6eff4da2018-01-01 20:27:45 -0800191impl<'a, T, P> Iterator for Elements<'a, T, P> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500192 type Item = Element<&'a T, &'a P>;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700193
David Tolnay6eff4da2018-01-01 20:27:45 -0800194 fn next(&mut self) -> Option<Self::Item> {
David Tolnay51382052017-12-27 13:46:21 -0500195 self.inner.next().map(|pair| match pair.1 {
David Tolnayf2cfd722017-12-31 18:02:51 -0500196 Some(ref p) => Element::Punctuated(&pair.0, p),
David Tolnay51382052017-12-27 13:46:21 -0500197 None => Element::End(&pair.0),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700198 })
199 }
200}
201
David Tolnay6eff4da2018-01-01 20:27:45 -0800202pub struct ElementsMut<'a, T: 'a, P: 'a> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500203 inner: slice::IterMut<'a, (T, Option<P>)>,
Alex Crichton164c5332017-07-06 13:18:34 -0700204}
205
David Tolnay6eff4da2018-01-01 20:27:45 -0800206impl<'a, T, P> Iterator for ElementsMut<'a, T, P> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500207 type Item = Element<&'a mut T, &'a mut P>;
Alex Crichton164c5332017-07-06 13:18:34 -0700208
David Tolnay6eff4da2018-01-01 20:27:45 -0800209 fn next(&mut self) -> Option<Self::Item> {
David Tolnay51382052017-12-27 13:46:21 -0500210 self.inner.next().map(|pair| match pair.1 {
David Tolnayf2cfd722017-12-31 18:02:51 -0500211 Some(ref mut p) => Element::Punctuated(&mut pair.0, p),
David Tolnay51382052017-12-27 13:46:21 -0500212 None => Element::End(&mut pair.0),
Alex Crichton164c5332017-07-06 13:18:34 -0700213 })
214 }
215}
216
David Tolnay6eff4da2018-01-01 20:27:45 -0800217pub struct IntoElements<T, P> {
218 inner: vec::IntoIter<(T, Option<P>)>,
219}
220
221impl<T, P> Iterator for IntoElements<T, P> {
222 type Item = Element<T, P>;
223
224 fn next(&mut self) -> Option<Self::Item> {
225 self.inner.next().map(|pair| match pair.1 {
226 Some(p) => Element::Punctuated(pair.0, p),
227 None => Element::End(pair.0),
228 })
229 }
230}
231
David Tolnayf2cfd722017-12-31 18:02:51 -0500232pub struct IntoIter<T, P> {
233 inner: vec::IntoIter<(T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700234}
235
David Tolnayf2cfd722017-12-31 18:02:51 -0500236impl<T, P> Iterator for IntoIter<T, P> {
David Tolnay6eff4da2018-01-01 20:27:45 -0800237 type Item = T;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700238
David Tolnay6eff4da2018-01-01 20:27:45 -0800239 fn next(&mut self) -> Option<Self::Item> {
240 self.inner.next().map(|pair| pair.0)
241 }
242}
243
244pub struct Iter<'a, T: 'a, P: 'a> {
245 inner: slice::Iter<'a, (T, Option<P>)>,
246}
247
248impl<'a, T, P> Iterator for Iter<'a, T, P> {
249 type Item = &'a T;
250
251 fn next(&mut self) -> Option<Self::Item> {
252 self.inner.next().map(|pair| &pair.0)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700253 }
254}
255
David Tolnaya0834b42018-01-01 21:30:02 -0800256pub struct IterMut<'a, T: 'a, P: 'a> {
257 inner: slice::IterMut<'a, (T, Option<P>)>,
258}
259
260impl<'a, T, P> Iterator for IterMut<'a, T, P> {
261 type Item = &'a mut T;
262
263 fn next(&mut self) -> Option<Self::Item> {
264 self.inner.next().map(|pair| &mut pair.0)
265 }
266}
267
David Tolnayf2cfd722017-12-31 18:02:51 -0500268pub enum Element<T, P> {
269 Punctuated(T, P),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700270 End(T),
271}
272
David Tolnayf2cfd722017-12-31 18:02:51 -0500273impl<T, P> Element<T, P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700274 pub fn into_item(self) -> T {
275 match self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500276 Element::Punctuated(t, _) | Element::End(t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700277 }
278 }
279
280 pub fn item(&self) -> &T {
281 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500282 Element::Punctuated(ref t, _) | Element::End(ref t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700283 }
284 }
285
286 pub fn item_mut(&mut self) -> &mut T {
287 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500288 Element::Punctuated(ref mut t, _) | Element::End(ref mut t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700289 }
290 }
291
David Tolnayf2cfd722017-12-31 18:02:51 -0500292 pub fn punct(&self) -> Option<&P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700293 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500294 Element::Punctuated(_, ref d) => Some(d),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700295 Element::End(_) => None,
296 }
297 }
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400298
David Tolnayf2cfd722017-12-31 18:02:51 -0500299 pub fn new(t: T, d: Option<P>) -> Self {
David Tolnay660fd1f2017-12-31 01:52:57 -0500300 match d {
David Tolnayf2cfd722017-12-31 18:02:51 -0500301 Some(d) => Element::Punctuated(t, d),
David Tolnay660fd1f2017-12-31 01:52:57 -0500302 None => Element::End(t),
303 }
304 }
305
David Tolnayf2cfd722017-12-31 18:02:51 -0500306 pub fn into_tuple(self) -> (T, Option<P>) {
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400307 match self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500308 Element::Punctuated(t, d) => (t, Some(d)),
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400309 Element::End(t) => (t, None),
310 }
311 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700312}
313
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700314#[cfg(feature = "parsing")]
315mod parsing {
David Tolnayf2cfd722017-12-31 18:02:51 -0500316 use super::Punctuated;
David Tolnayc5ab8c62017-12-26 16:43:39 -0500317 use synom::Synom;
318 use cursor::Cursor;
David Tolnay203557a2017-12-27 23:59:33 -0500319 use parse_error;
320 use synom::PResult;
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700321
David Tolnayf2cfd722017-12-31 18:02:51 -0500322 impl<T, P> Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500323 where
324 T: Synom,
David Tolnayf2cfd722017-12-31 18:02:51 -0500325 P: Synom,
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700326 {
David Tolnay51382052017-12-27 13:46:21 -0500327 pub fn parse_separated(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700328 Self::parse(input, T::parse, false)
329 }
330
David Tolnay51382052017-12-27 13:46:21 -0500331 pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700332 Self::parse_separated_nonempty_with(input, T::parse)
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700333 }
334
David Tolnay51382052017-12-27 13:46:21 -0500335 pub fn parse_terminated(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700336 Self::parse_terminated_with(input, T::parse)
337 }
Nika Layzellb49a9e52017-12-05 13:31:52 -0500338
David Tolnay51382052017-12-27 13:46:21 -0500339 pub fn parse_terminated_nonempty(input: Cursor) -> PResult<Self> {
Nika Layzellb49a9e52017-12-05 13:31:52 -0500340 Self::parse_terminated_nonempty_with(input, T::parse)
341 }
Alex Crichton954046c2017-05-30 21:49:42 -0700342 }
343
David Tolnayf2cfd722017-12-31 18:02:51 -0500344 impl<T, P> Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500345 where
David Tolnayf2cfd722017-12-31 18:02:51 -0500346 P: Synom,
Alex Crichton954046c2017-05-30 21:49:42 -0700347 {
David Tolnaydc03aec2017-12-30 01:54:18 -0500348 pub fn parse_separated_with(
349 input: Cursor,
350 parse: fn(Cursor) -> PResult<T>,
351 ) -> PResult<Self> {
352 Self::parse(input, parse, false)
353 }
354
Alex Crichton954046c2017-05-30 21:49:42 -0700355 pub fn parse_separated_nonempty_with(
David Tolnay51382052017-12-27 13:46:21 -0500356 input: Cursor,
357 parse: fn(Cursor) -> PResult<T>,
358 ) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700359 match Self::parse(input, parse, false) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500360 Ok((ref b, _)) if b.is_empty() => parse_error(),
Alex Crichton954046c2017-05-30 21:49:42 -0700361 other => other,
362 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700363 }
364
Alex Crichton954046c2017-05-30 21:49:42 -0700365 pub fn parse_terminated_with(
David Tolnay51382052017-12-27 13:46:21 -0500366 input: Cursor,
367 parse: fn(Cursor) -> PResult<T>,
368 ) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700369 Self::parse(input, parse, true)
370 }
371
Nika Layzellb49a9e52017-12-05 13:31:52 -0500372 pub fn parse_terminated_nonempty_with(
David Tolnay51382052017-12-27 13:46:21 -0500373 input: Cursor,
374 parse: fn(Cursor) -> PResult<T>,
375 ) -> PResult<Self> {
Nika Layzellb49a9e52017-12-05 13:31:52 -0500376 match Self::parse(input, parse, true) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500377 Ok((ref b, _)) if b.is_empty() => parse_error(),
Nika Layzellb49a9e52017-12-05 13:31:52 -0500378 other => other,
379 }
380 }
381
David Tolnay51382052017-12-27 13:46:21 -0500382 fn parse(
383 mut input: Cursor,
384 parse: fn(Cursor) -> PResult<T>,
385 terminated: bool,
386 ) -> PResult<Self> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500387 let mut res = Punctuated::new();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700388
389 // get the first element
Alex Crichton954046c2017-05-30 21:49:42 -0700390 match parse(input) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500391 Err(_) => Ok((res, input)),
392 Ok((o, i)) => {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400393 if i == input {
Michael Layzell760fd662017-05-31 22:46:05 -0400394 return parse_error();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700395 }
396 input = i;
David Tolnaya0834b42018-01-01 21:30:02 -0800397 res.push_item(o);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700398
399 // get the separator first
David Tolnayf2cfd722017-12-31 18:02:51 -0500400 while let Ok((s, i2)) = P::parse(input) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400401 if i2 == input {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700402 break;
403 }
404
405 // get the element next
David Tolnayf4aa6b42017-12-31 16:40:33 -0500406 if let Ok((o3, i3)) = parse(i2) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400407 if i3 == i2 {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700408 break;
409 }
David Tolnaya0834b42018-01-01 21:30:02 -0800410 res.push_punct(s);
411 res.push_item(o3);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700412 input = i3;
413 } else {
414 break;
415 }
416 }
417 if terminated {
David Tolnayf2cfd722017-12-31 18:02:51 -0500418 if let Ok((sep, after)) = P::parse(input) {
David Tolnaya0834b42018-01-01 21:30:02 -0800419 res.push_punct(sep);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700420 input = after;
421 }
422 }
David Tolnayf4aa6b42017-12-31 16:40:33 -0500423 Ok((res, input))
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700424 }
425 }
426 }
427 }
428}
429
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700430#[cfg(feature = "printing")]
431mod printing {
432 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500433 use quote::{ToTokens, Tokens};
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700434
David Tolnayf2cfd722017-12-31 18:02:51 -0500435 impl<T, P> ToTokens for Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500436 where
437 T: ToTokens,
David Tolnayf2cfd722017-12-31 18:02:51 -0500438 P: ToTokens,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700439 {
440 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaya0834b42018-01-01 21:30:02 -0800441 tokens.append_all(self.elements())
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700442 }
443 }
444
David Tolnayf2cfd722017-12-31 18:02:51 -0500445 impl<T, P> ToTokens for Element<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500446 where
447 T: ToTokens,
David Tolnayf2cfd722017-12-31 18:02:51 -0500448 P: ToTokens,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700449 {
450 fn to_tokens(&self, tokens: &mut Tokens) {
451 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500452 Element::Punctuated(ref a, ref b) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700453 a.to_tokens(tokens);
454 b.to_tokens(tokens);
455 }
456 Element::End(ref a) => a.to_tokens(tokens),
457 }
458 }
459 }
460}