blob: dc8c4ea3578a1e0eaad1d27bfc92b4e077782763 [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 Tolnay660fd1f2017-12-31 01:52:57 -050096 self.inner.last().map(|last| last.1.is_some()).unwrap_or(false)
Alex Crichtonccbb45d2017-05-23 10:58:24 -070097 }
Michael Layzell3936ceb2017-07-08 00:28:36 -040098
David Tolnayf2cfd722017-12-31 18:02:51 -050099 /// Returns true if either this `Punctuated` is empty, or it has a trailing
100 /// punctuation.
David Tolnaydc03aec2017-12-30 01:54:18 -0500101 ///
David Tolnaya0834b42018-01-01 21:30:02 -0800102 /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
Michael Layzell3936ceb2017-07-08 00:28:36 -0400103 pub fn empty_or_trailing(&self) -> bool {
David Tolnay660fd1f2017-12-31 01:52:57 -0500104 self.inner.last().map(|last| last.1.is_some()).unwrap_or(true)
Michael Layzell3936ceb2017-07-08 00:28:36 -0400105 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700106}
107
David Tolnaya0834b42018-01-01 21:30:02 -0800108impl<T, P> Punctuated<T, P>
109where
110 P: Default,
111{
112 pub fn push(&mut self, item: T) {
113 if !self.empty_or_trailing() {
114 self.push_punct(Default::default());
115 }
116 self.push_item(item);
117 }
118}
119
Nika Layzelld73a3652017-10-24 08:57:05 -0400120#[cfg(feature = "extra-traits")]
David Tolnayf2cfd722017-12-31 18:02:51 -0500121impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
Nika Layzelld73a3652017-10-24 08:57:05 -0400122 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123 self.inner.fmt(f)
124 }
125}
126
David Tolnayf2cfd722017-12-31 18:02:51 -0500127impl<T, P> FromIterator<Element<T, P>> for Punctuated<T, P> {
128 fn from_iter<I: IntoIterator<Item = Element<T, P>>>(i: I) -> Self {
129 let mut ret = Punctuated::new();
Alex Crichton24f12822017-07-14 07:15:32 -0700130 ret.extend(i);
Alex Crichton954046c2017-05-30 21:49:42 -0700131 ret
132 }
133}
134
David Tolnayf2cfd722017-12-31 18:02:51 -0500135impl<T, P> Extend<Element<T, P>> for Punctuated<T, P> {
136 fn extend<I: IntoIterator<Item = Element<T, P>>>(&mut self, i: I) {
David Tolnay660fd1f2017-12-31 01:52:57 -0500137 for elem in i {
138 match elem {
David Tolnayf2cfd722017-12-31 18:02:51 -0500139 Element::Punctuated(a, b) => self.inner.push((a, Some(b))),
Alex Crichton24f12822017-07-14 07:15:32 -0700140 Element::End(a) => self.inner.push((a, None)),
141 }
142 }
143 }
144}
145
David Tolnayf2cfd722017-12-31 18:02:51 -0500146impl<T, P> IntoIterator for Punctuated<T, P> {
David Tolnay6eff4da2018-01-01 20:27:45 -0800147 type Item = T;
David Tolnayf2cfd722017-12-31 18:02:51 -0500148 type IntoIter = IntoIter<T, P>;
Alex Crichton954046c2017-05-30 21:49:42 -0700149
David Tolnaybb4ca9f2017-12-26 12:28:58 -0500150 fn into_iter(self) -> Self::IntoIter {
David Tolnay51382052017-12-27 13:46:21 -0500151 IntoIter {
152 inner: self.inner.into_iter(),
153 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700154 }
155}
156
David Tolnay6eff4da2018-01-01 20:27:45 -0800157impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
158 type Item = &'a T;
159 type IntoIter = Iter<'a, T, P>;
160
161 fn into_iter(self) -> Self::IntoIter {
162 Punctuated::iter(self)
163 }
164}
165
David Tolnaya0834b42018-01-01 21:30:02 -0800166impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
167 type Item = &'a mut T;
168 type IntoIter = IterMut<'a, T, P>;
169
170 fn into_iter(self) -> Self::IntoIter {
171 Punctuated::iter_mut(self)
172 }
173}
174
David Tolnayf2cfd722017-12-31 18:02:51 -0500175impl<T, P> Default for Punctuated<T, P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700176 fn default() -> Self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500177 Punctuated::new()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700178 }
179}
180
David Tolnay6eff4da2018-01-01 20:27:45 -0800181pub struct Elements<'a, T: 'a, P: 'a> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500182 inner: slice::Iter<'a, (T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700183}
184
David Tolnay6eff4da2018-01-01 20:27:45 -0800185impl<'a, T, P> Iterator for Elements<'a, T, P> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500186 type Item = Element<&'a T, &'a P>;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700187
David Tolnay6eff4da2018-01-01 20:27:45 -0800188 fn next(&mut self) -> Option<Self::Item> {
David Tolnay51382052017-12-27 13:46:21 -0500189 self.inner.next().map(|pair| match pair.1 {
David Tolnayf2cfd722017-12-31 18:02:51 -0500190 Some(ref p) => Element::Punctuated(&pair.0, p),
David Tolnay51382052017-12-27 13:46:21 -0500191 None => Element::End(&pair.0),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700192 })
193 }
194}
195
David Tolnay6eff4da2018-01-01 20:27:45 -0800196pub struct ElementsMut<'a, T: 'a, P: 'a> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500197 inner: slice::IterMut<'a, (T, Option<P>)>,
Alex Crichton164c5332017-07-06 13:18:34 -0700198}
199
David Tolnay6eff4da2018-01-01 20:27:45 -0800200impl<'a, T, P> Iterator for ElementsMut<'a, T, P> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500201 type Item = Element<&'a mut T, &'a mut P>;
Alex Crichton164c5332017-07-06 13:18:34 -0700202
David Tolnay6eff4da2018-01-01 20:27:45 -0800203 fn next(&mut self) -> Option<Self::Item> {
David Tolnay51382052017-12-27 13:46:21 -0500204 self.inner.next().map(|pair| match pair.1 {
David Tolnayf2cfd722017-12-31 18:02:51 -0500205 Some(ref mut p) => Element::Punctuated(&mut pair.0, p),
David Tolnay51382052017-12-27 13:46:21 -0500206 None => Element::End(&mut pair.0),
Alex Crichton164c5332017-07-06 13:18:34 -0700207 })
208 }
209}
210
David Tolnay6eff4da2018-01-01 20:27:45 -0800211pub struct IntoElements<T, P> {
212 inner: vec::IntoIter<(T, Option<P>)>,
213}
214
215impl<T, P> Iterator for IntoElements<T, P> {
216 type Item = Element<T, P>;
217
218 fn next(&mut self) -> Option<Self::Item> {
219 self.inner.next().map(|pair| match pair.1 {
220 Some(p) => Element::Punctuated(pair.0, p),
221 None => Element::End(pair.0),
222 })
223 }
224}
225
David Tolnayf2cfd722017-12-31 18:02:51 -0500226pub struct IntoIter<T, P> {
227 inner: vec::IntoIter<(T, Option<P>)>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700228}
229
David Tolnayf2cfd722017-12-31 18:02:51 -0500230impl<T, P> Iterator for IntoIter<T, P> {
David Tolnay6eff4da2018-01-01 20:27:45 -0800231 type Item = T;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700232
David Tolnay6eff4da2018-01-01 20:27:45 -0800233 fn next(&mut self) -> Option<Self::Item> {
234 self.inner.next().map(|pair| pair.0)
235 }
236}
237
238pub struct Iter<'a, T: 'a, P: 'a> {
239 inner: slice::Iter<'a, (T, Option<P>)>,
240}
241
242impl<'a, T, P> Iterator for Iter<'a, T, P> {
243 type Item = &'a T;
244
245 fn next(&mut self) -> Option<Self::Item> {
246 self.inner.next().map(|pair| &pair.0)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700247 }
248}
249
David Tolnaya0834b42018-01-01 21:30:02 -0800250pub struct IterMut<'a, T: 'a, P: 'a> {
251 inner: slice::IterMut<'a, (T, Option<P>)>,
252}
253
254impl<'a, T, P> Iterator for IterMut<'a, T, P> {
255 type Item = &'a mut T;
256
257 fn next(&mut self) -> Option<Self::Item> {
258 self.inner.next().map(|pair| &mut pair.0)
259 }
260}
261
David Tolnayf2cfd722017-12-31 18:02:51 -0500262pub enum Element<T, P> {
263 Punctuated(T, P),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700264 End(T),
265}
266
David Tolnayf2cfd722017-12-31 18:02:51 -0500267impl<T, P> Element<T, P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700268 pub fn into_item(self) -> T {
269 match self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500270 Element::Punctuated(t, _) | Element::End(t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700271 }
272 }
273
274 pub fn item(&self) -> &T {
275 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500276 Element::Punctuated(ref t, _) | Element::End(ref t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700277 }
278 }
279
280 pub fn item_mut(&mut self) -> &mut T {
281 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500282 Element::Punctuated(ref mut t, _) | Element::End(ref mut t) => t,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700283 }
284 }
285
David Tolnayf2cfd722017-12-31 18:02:51 -0500286 pub fn punct(&self) -> Option<&P> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700287 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500288 Element::Punctuated(_, ref d) => Some(d),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700289 Element::End(_) => None,
290 }
291 }
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400292
David Tolnayf2cfd722017-12-31 18:02:51 -0500293 pub fn new(t: T, d: Option<P>) -> Self {
David Tolnay660fd1f2017-12-31 01:52:57 -0500294 match d {
David Tolnayf2cfd722017-12-31 18:02:51 -0500295 Some(d) => Element::Punctuated(t, d),
David Tolnay660fd1f2017-12-31 01:52:57 -0500296 None => Element::End(t),
297 }
298 }
299
David Tolnayf2cfd722017-12-31 18:02:51 -0500300 pub fn into_tuple(self) -> (T, Option<P>) {
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400301 match self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500302 Element::Punctuated(t, d) => (t, Some(d)),
Nika Layzellcda7ebd2017-10-24 23:10:44 -0400303 Element::End(t) => (t, None),
304 }
305 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700306}
307
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700308#[cfg(feature = "parsing")]
309mod parsing {
David Tolnayf2cfd722017-12-31 18:02:51 -0500310 use super::Punctuated;
David Tolnayc5ab8c62017-12-26 16:43:39 -0500311 use synom::Synom;
312 use cursor::Cursor;
David Tolnay203557a2017-12-27 23:59:33 -0500313 use parse_error;
314 use synom::PResult;
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700315
David Tolnayf2cfd722017-12-31 18:02:51 -0500316 impl<T, P> Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500317 where
318 T: Synom,
David Tolnayf2cfd722017-12-31 18:02:51 -0500319 P: Synom,
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700320 {
David Tolnay51382052017-12-27 13:46:21 -0500321 pub fn parse_separated(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700322 Self::parse(input, T::parse, false)
323 }
324
David Tolnay51382052017-12-27 13:46:21 -0500325 pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700326 Self::parse_separated_nonempty_with(input, T::parse)
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700327 }
328
David Tolnay51382052017-12-27 13:46:21 -0500329 pub fn parse_terminated(input: Cursor) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700330 Self::parse_terminated_with(input, T::parse)
331 }
Nika Layzellb49a9e52017-12-05 13:31:52 -0500332
David Tolnay51382052017-12-27 13:46:21 -0500333 pub fn parse_terminated_nonempty(input: Cursor) -> PResult<Self> {
Nika Layzellb49a9e52017-12-05 13:31:52 -0500334 Self::parse_terminated_nonempty_with(input, T::parse)
335 }
Alex Crichton954046c2017-05-30 21:49:42 -0700336 }
337
David Tolnayf2cfd722017-12-31 18:02:51 -0500338 impl<T, P> Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500339 where
David Tolnayf2cfd722017-12-31 18:02:51 -0500340 P: Synom,
Alex Crichton954046c2017-05-30 21:49:42 -0700341 {
David Tolnaydc03aec2017-12-30 01:54:18 -0500342 pub fn parse_separated_with(
343 input: Cursor,
344 parse: fn(Cursor) -> PResult<T>,
345 ) -> PResult<Self> {
346 Self::parse(input, parse, false)
347 }
348
Alex Crichton954046c2017-05-30 21:49:42 -0700349 pub fn parse_separated_nonempty_with(
David Tolnay51382052017-12-27 13:46:21 -0500350 input: Cursor,
351 parse: fn(Cursor) -> PResult<T>,
352 ) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700353 match Self::parse(input, parse, false) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500354 Ok((ref b, _)) if b.is_empty() => parse_error(),
Alex Crichton954046c2017-05-30 21:49:42 -0700355 other => other,
356 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700357 }
358
Alex Crichton954046c2017-05-30 21:49:42 -0700359 pub fn parse_terminated_with(
David Tolnay51382052017-12-27 13:46:21 -0500360 input: Cursor,
361 parse: fn(Cursor) -> PResult<T>,
362 ) -> PResult<Self> {
Alex Crichton954046c2017-05-30 21:49:42 -0700363 Self::parse(input, parse, true)
364 }
365
Nika Layzellb49a9e52017-12-05 13:31:52 -0500366 pub fn parse_terminated_nonempty_with(
David Tolnay51382052017-12-27 13:46:21 -0500367 input: Cursor,
368 parse: fn(Cursor) -> PResult<T>,
369 ) -> PResult<Self> {
Nika Layzellb49a9e52017-12-05 13:31:52 -0500370 match Self::parse(input, parse, true) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500371 Ok((ref b, _)) if b.is_empty() => parse_error(),
Nika Layzellb49a9e52017-12-05 13:31:52 -0500372 other => other,
373 }
374 }
375
David Tolnay51382052017-12-27 13:46:21 -0500376 fn parse(
377 mut input: Cursor,
378 parse: fn(Cursor) -> PResult<T>,
379 terminated: bool,
380 ) -> PResult<Self> {
David Tolnayf2cfd722017-12-31 18:02:51 -0500381 let mut res = Punctuated::new();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700382
383 // get the first element
Alex Crichton954046c2017-05-30 21:49:42 -0700384 match parse(input) {
David Tolnayf4aa6b42017-12-31 16:40:33 -0500385 Err(_) => Ok((res, input)),
386 Ok((o, i)) => {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400387 if i == input {
Michael Layzell760fd662017-05-31 22:46:05 -0400388 return parse_error();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700389 }
390 input = i;
David Tolnaya0834b42018-01-01 21:30:02 -0800391 res.push_item(o);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700392
393 // get the separator first
David Tolnayf2cfd722017-12-31 18:02:51 -0500394 while let Ok((s, i2)) = P::parse(input) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400395 if i2 == input {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700396 break;
397 }
398
399 // get the element next
David Tolnayf4aa6b42017-12-31 16:40:33 -0500400 if let Ok((o3, i3)) = parse(i2) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400401 if i3 == i2 {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700402 break;
403 }
David Tolnaya0834b42018-01-01 21:30:02 -0800404 res.push_punct(s);
405 res.push_item(o3);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700406 input = i3;
407 } else {
408 break;
409 }
410 }
411 if terminated {
David Tolnayf2cfd722017-12-31 18:02:51 -0500412 if let Ok((sep, after)) = P::parse(input) {
David Tolnaya0834b42018-01-01 21:30:02 -0800413 res.push_punct(sep);
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700414 input = after;
415 }
416 }
David Tolnayf4aa6b42017-12-31 16:40:33 -0500417 Ok((res, input))
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700418 }
419 }
420 }
421 }
422}
423
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700424#[cfg(feature = "printing")]
425mod printing {
426 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500427 use quote::{ToTokens, Tokens};
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700428
David Tolnayf2cfd722017-12-31 18:02:51 -0500429 impl<T, P> ToTokens for Punctuated<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500430 where
431 T: ToTokens,
David Tolnayf2cfd722017-12-31 18:02:51 -0500432 P: ToTokens,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700433 {
434 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaya0834b42018-01-01 21:30:02 -0800435 tokens.append_all(self.elements())
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700436 }
437 }
438
David Tolnayf2cfd722017-12-31 18:02:51 -0500439 impl<T, P> ToTokens for Element<T, P>
David Tolnay51382052017-12-27 13:46:21 -0500440 where
441 T: ToTokens,
David Tolnayf2cfd722017-12-31 18:02:51 -0500442 P: ToTokens,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700443 {
444 fn to_tokens(&self, tokens: &mut Tokens) {
445 match *self {
David Tolnayf2cfd722017-12-31 18:02:51 -0500446 Element::Punctuated(ref a, ref b) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700447 a.to_tokens(tokens);
448 b.to_tokens(tokens);
449 }
450 Element::End(ref a) => a.to_tokens(tokens),
451 }
452 }
453 }
454}