blob: a6d297d8fc7bbd3210ae23c19a89d9a1944d0a80 [file] [log] [blame]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001use std::iter::FromIterator;
2use std::slice;
3use std::vec;
4
Alex Crichton7b9e02f2017-05-30 15:54:33 -07005#[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash, Debug))]
6#[cfg_attr(feature = "clone-impls", derive(Clone))]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07007pub struct Delimited<T, D> {
8 inner: Vec<(T, Option<D>)>
9}
10
11impl<T, D> Delimited<T, D> {
12 pub fn new() -> Delimited<T, D> {
13 Delimited {
14 inner: Vec::new(),
15 }
16 }
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
26 pub fn get(&self, idx: usize) -> Element<&T, &D> {
27 let (ref t, ref d) = self.inner[idx];
28 match *d {
29 Some(ref d) => Element::Delimited(t, d),
30 None => Element::End(t),
31 }
32 }
33
34 pub fn get_mut(&mut self, idx: usize) -> Element<&mut T, &mut D> {
35 let (ref mut t, ref mut d) = self.inner[idx];
36 match *d {
37 Some(ref mut d) => Element::Delimited(t, d),
38 None => Element::End(t),
39 }
40 }
41
Alex Crichton0aa50e02017-07-07 20:59:03 -070042 pub fn first(&self) -> Option<Element<&T, &D>> {
43 self.inner.first().map(|&(ref t, ref d)| {
44 match *d {
45 Some(ref d) => Element::Delimited(t, d),
46 None => Element::End(t),
47 }
48 })
49 }
50
51 pub fn first_mut(&mut self) -> Option<Element<&mut T, &mut D>> {
52 self.inner.first_mut().map(|&mut (ref mut t, ref mut d)| {
53 match *d {
54 Some(ref mut d) => Element::Delimited(t, d),
55 None => Element::End(t),
56 }
57 })
58 }
59
60 pub fn last(&self) -> Option<Element<&T, &D>> {
61 self.inner.last().map(|&(ref t, ref d)| {
62 match *d {
63 Some(ref d) => Element::Delimited(t, d),
64 None => Element::End(t),
65 }
66 })
67 }
68
69 pub fn last_mut(&mut self) -> Option<Element<&mut T, &mut D>> {
70 self.inner.last_mut().map(|&mut (ref mut t, ref mut d)| {
71 match *d {
72 Some(ref mut d) => Element::Delimited(t, d),
73 None => Element::End(t),
74 }
75 })
76 }
77
Alex Crichtonccbb45d2017-05-23 10:58:24 -070078 pub fn iter(&self) -> Iter<T, D> {
79 Iter { inner: self.inner.iter() }
80 }
81
Alex Crichton164c5332017-07-06 13:18:34 -070082 pub fn iter_mut(&mut self) -> IterMut<T, D> {
83 IterMut { inner: self.inner.iter_mut() }
84 }
85
Alex Crichtonccbb45d2017-05-23 10:58:24 -070086 pub fn items(&self) -> Items<T, D> {
87 Items { inner: self.inner.iter() }
88 }
89
90 pub fn push(&mut self, token: Element<T, D>) {
Alex Crichton954046c2017-05-30 21:49:42 -070091 assert!(self.is_empty() || self.trailing_delim());
Alex Crichtonccbb45d2017-05-23 10:58:24 -070092 match token {
93 Element::Delimited(t, d) => self.inner.push((t, Some(d))),
94 Element::End(t) => self.inner.push((t, None)),
95 }
96 }
97
98 pub fn push_first(&mut self, token: T) {
99 assert!(self.is_empty());
100 self.inner.push((token, None));
101 }
102
103 pub fn push_next(&mut self, token: T, delimiter: D) {
104 self.push_trailing(delimiter);
105 self.inner.push((token, None));
106 }
107
108 pub fn push_trailing(&mut self, delimiter: D) {
109 let len = self.len();
110 assert!(self.inner[len - 1].1.is_none());
111 self.inner[len - 1].1 = Some(delimiter);
112 }
113
114 pub fn push_default(&mut self, token: T) where D: Default {
Alex Crichton337cd462017-07-06 14:47:25 -0700115 if self.is_empty() || self.trailing_delim() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700116 self.inner.push((token, None));
117 } else {
118 self.push_next(token, D::default());
119 }
120 }
121
122 pub fn pop(&mut self) -> Option<Element<T, D>> {
123 self.inner.pop().map(|e| {
124 match e {
125 (t, Some(d)) => Element::Delimited(t, d),
126 (t, None) => Element::End(t),
127 }
128 })
129 }
130
131 pub fn into_vec(self) -> Vec<T> {
132 self.inner.into_iter().map(|t| t.0).collect()
133 }
134
135 pub fn trailing_delim(&self) -> bool {
136 self.inner[self.inner.len() - 1].1.is_some()
137 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400138
139 /// Returns true if either this `Delimited` is empty, or it has a trailing
140 /// delimiter. This is useful within `ToTokens` implementations for `syn`.
141 #[doc(hidden)]
142 pub fn empty_or_trailing(&self) -> bool {
143 self.is_empty() || self.trailing_delim()
144 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700145}
146
147impl<T, D> From<Vec<(T, Option<D>)>> for Delimited<T, D> {
148 fn from(v: Vec<(T, Option<D>)>) -> Self {
149 Delimited {
150 inner: v,
151 }
152 }
153}
154
155impl<T, D> From<Vec<T>> for Delimited<T, D>
156 where D: Default,
157{
158 fn from(v: Vec<T>) -> Self {
Alex Crichtonafb49d22017-07-06 14:47:37 -0700159 let len = v.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700160 Delimited {
161 inner: v.into_iter().enumerate().map(|(i, item)| {
Alex Crichtonafb49d22017-07-06 14:47:37 -0700162 (item, if i + 1 == len {None} else {Some(D::default())})
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700163 }).collect(),
164 }
165 }
166}
167
168impl<T, D> FromIterator<Element<T, D>> for Delimited<T, D> {
169 fn from_iter<I: IntoIterator<Item = Element<T, D>>>(i: I) -> Self {
170 let mut ret = Delimited::new();
Alex Crichton24f12822017-07-14 07:15:32 -0700171 ret.extend(i);
Alex Crichton954046c2017-05-30 21:49:42 -0700172 ret
173 }
174}
175
Alex Crichtond3743d12017-07-07 20:55:24 -0700176impl<T, D> FromIterator<T> for Delimited<T, D>
177 where D: Default,
178{
179 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
180 let mut ret = Delimited::new();
Alex Crichton24f12822017-07-14 07:15:32 -0700181 ret.extend(i);
Alex Crichtond3743d12017-07-07 20:55:24 -0700182 ret
183 }
184}
185
Alex Crichton24f12822017-07-14 07:15:32 -0700186impl<T, D> Extend<Element<T, D>> for Delimited<T, D> {
187 fn extend<I: IntoIterator<Item = Element<T, D>>>(&mut self, i: I) {
188 for element in i {
189 match element {
190 Element::Delimited(a, b) => self.inner.push((a, Some(b))),
191 Element::End(a) => self.inner.push((a, None)),
192 }
193 }
194 }
195}
196
197impl<T, D> Extend<T> for Delimited<T, D>
198 where D: Default,
199{
200 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
201 for element in i {
202 self.push_default(element);
203 }
204 }
205}
206
Alex Crichton954046c2017-05-30 21:49:42 -0700207impl<'a, T, D> IntoIterator for &'a Delimited<T, D> {
208 type Item = Element<&'a T, &'a D>;
209 type IntoIter = Iter<'a, T, D>;
210
211 fn into_iter(self) -> Iter<'a, T, D> {
212 <Delimited<T, D>>::iter(self)
213 }
214}
215
216impl<T, D> IntoIterator for Delimited<T, D> {
217 type Item = Element<T, D>;
218 type IntoIter = IntoIter<T, D>;
219
220 fn into_iter(self) -> IntoIter<T, D> {
221 IntoIter { inner: self.inner.into_iter() }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700222 }
223}
224
225impl<T, D> Default for Delimited<T, D> {
226 fn default() -> Self {
227 Delimited::new()
228 }
229}
230
231pub struct Iter<'a, T: 'a, D: 'a> {
232 inner: slice::Iter<'a, (T, Option<D>)>,
233}
234
235impl<'a, T, D> Iterator for Iter<'a, T, D> {
236 type Item = Element<&'a T, &'a D>;
237
238 fn next(&mut self) -> Option<Element<&'a T, &'a D>> {
239 self.inner.next().map(|pair| {
240 match pair.1 {
241 Some(ref delimited) => Element::Delimited(&pair.0, delimited),
242 None => Element::End(&pair.0),
243 }
244 })
245 }
246}
247
Alex Crichton164c5332017-07-06 13:18:34 -0700248pub struct IterMut<'a, T: 'a, D: 'a> {
249 inner: slice::IterMut<'a, (T, Option<D>)>,
250}
251
252impl<'a, T, D> Iterator for IterMut<'a, T, D> {
253 type Item = Element<&'a mut T, &'a mut D>;
254
255 fn next(&mut self) -> Option<Element<&'a mut T, &'a mut D>> {
256 self.inner.next().map(|pair| {
257 match pair.1 {
258 Some(ref mut delimited) => Element::Delimited(&mut pair.0, delimited),
259 None => Element::End(&mut pair.0),
260 }
261 })
262 }
263}
264
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700265pub struct Items<'a, T: 'a, D: 'a> {
266 inner: slice::Iter<'a, (T, Option<D>)>,
267}
268
269impl<'a, T, D> Iterator for Items<'a, T, D> {
270 type Item = &'a T;
271
272 fn next(&mut self) -> Option<&'a T> {
273 self.inner.next().map(|pair| &pair.0)
274 }
275}
276
277pub struct IntoIter<T, D> {
278 inner: vec::IntoIter<(T, Option<D>)>,
279}
280
281impl<T, D> Iterator for IntoIter<T, D> {
282 type Item = Element<T, D>;
283
284 fn next(&mut self) -> Option<Element<T, D>> {
285 self.inner.next().map(|pair| {
286 match pair.1 {
287 Some(v) => Element::Delimited(pair.0, v),
288 None => Element::End(pair.0)
289 }
290 })
291 }
292}
293
294pub enum Element<T, D> {
295 Delimited(T, D),
296 End(T),
297}
298
299impl<T, D> Element<T, D> {
300 pub fn into_item(self) -> T {
301 match self {
302 Element::Delimited(t, _) |
303 Element::End(t) => t,
304 }
305 }
306
307 pub fn item(&self) -> &T {
308 match *self {
309 Element::Delimited(ref t, _) |
310 Element::End(ref t) => t,
311 }
312 }
313
314 pub fn item_mut(&mut self) -> &mut T {
315 match *self {
316 Element::Delimited(ref mut t, _) |
317 Element::End(ref mut t) => t,
318 }
319 }
320
321 pub fn delimiter(&self) -> Option<&D> {
322 match *self {
323 Element::Delimited(_, ref d) => Some(d),
324 Element::End(_) => None,
325 }
326 }
327}
328
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700329#[cfg(feature = "parsing")]
330mod parsing {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700331 use super::Delimited;
Michael Layzell760fd662017-05-31 22:46:05 -0400332 use {PResult, Cursor, Synom, parse_error};
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700333
334 impl<T, D> Delimited<T, D>
335 where T: Synom,
336 D: Synom,
337 {
Michael Layzell760fd662017-05-31 22:46:05 -0400338 pub fn parse_separated(input: Cursor) -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700339 {
Alex Crichton954046c2017-05-30 21:49:42 -0700340 Self::parse(input, T::parse, false)
341 }
342
Michael Layzell760fd662017-05-31 22:46:05 -0400343 pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700344 {
345 Self::parse_separated_nonempty_with(input, T::parse)
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700346 }
347
Michael Layzell760fd662017-05-31 22:46:05 -0400348 pub fn parse_terminated(input: Cursor) -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700349 {
Alex Crichton954046c2017-05-30 21:49:42 -0700350 Self::parse_terminated_with(input, T::parse)
351 }
352 }
353
354 impl<T, D> Delimited<T, D>
355 where D: Synom,
356 {
357 pub fn parse_separated_nonempty_with(
Michael Layzell760fd662017-05-31 22:46:05 -0400358 input: Cursor,
359 parse: fn(Cursor) -> PResult<T>)
360 -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700361 {
362 match Self::parse(input, parse, false) {
Michael Layzell760fd662017-05-31 22:46:05 -0400363 Ok((_, ref b)) if b.is_empty() => parse_error(),
Alex Crichton954046c2017-05-30 21:49:42 -0700364 other => other,
365 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700366 }
367
Alex Crichton954046c2017-05-30 21:49:42 -0700368 pub fn parse_terminated_with(
Michael Layzell760fd662017-05-31 22:46:05 -0400369 input: Cursor,
370 parse: fn(Cursor) -> PResult<T>)
371 -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700372 {
373 Self::parse(input, parse, true)
374 }
375
Michael Layzell760fd662017-05-31 22:46:05 -0400376 fn parse(mut input: Cursor,
377 parse: fn(Cursor) -> PResult<T>,
Alex Crichton954046c2017-05-30 21:49:42 -0700378 terminated: bool)
Michael Layzell760fd662017-05-31 22:46:05 -0400379 -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700380 {
381 let mut res = Delimited::new();
382
383 // get the first element
Alex Crichton954046c2017-05-30 21:49:42 -0700384 match parse(input) {
Michael Layzell760fd662017-05-31 22:46:05 -0400385 Err(_) => Ok((input, res)),
386 Ok((i, o)) => {
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;
391 res.push_first(o);
392
393 // get the separator first
Michael Layzell760fd662017-05-31 22:46:05 -0400394 while let Ok((i2, s)) = D::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
Michael Layzell760fd662017-05-31 22:46:05 -0400400 if let Ok((i3, o3)) = parse(i2) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400401 if i3 == i2 {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700402 break;
403 }
404 res.push_next(o3, s);
405 input = i3;
406 } else {
407 break;
408 }
409 }
410 if terminated {
Michael Layzell760fd662017-05-31 22:46:05 -0400411 if let Ok((after, sep)) = D::parse(input) {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700412 res.push_trailing(sep);
413 input = after;
414 }
415 }
Michael Layzell760fd662017-05-31 22:46:05 -0400416 Ok((input, res))
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700417 }
418 }
419 }
420 }
421}
422
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700423#[cfg(feature = "printing")]
424mod printing {
425 use super::*;
426 use quote::{Tokens, ToTokens};
427
428
429 impl<T, D> ToTokens for Delimited<T, D>
430 where T: ToTokens,
431 D: ToTokens,
432 {
433 fn to_tokens(&self, tokens: &mut Tokens) {
434 tokens.append_all(self.iter())
435 }
436 }
437
438 impl<T, D> ToTokens for Element<T, D>
439 where T: ToTokens,
440 D: ToTokens,
441 {
442 fn to_tokens(&self, tokens: &mut Tokens) {
443 match *self {
444 Element::Delimited(ref a, ref b) => {
445 a.to_tokens(tokens);
446 b.to_tokens(tokens);
447 }
448 Element::End(ref a) => a.to_tokens(tokens),
449 }
450 }
451 }
452}