blob: f9041b311a484b6cfcb1a1cb58f3ba1f33f4afa9 [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();
171 for element in i {
172 match element {
173 Element::Delimited(a, b) => ret.inner.push((a, Some(b))),
174 Element::End(a) => ret.inner.push((a, None)),
175 }
176 }
Alex Crichton954046c2017-05-30 21:49:42 -0700177 ret
178 }
179}
180
Alex Crichtond3743d12017-07-07 20:55:24 -0700181impl<T, D> FromIterator<T> for Delimited<T, D>
182 where D: Default,
183{
184 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
185 let mut ret = Delimited::new();
186 for element in i {
187 ret.push_default(element);
188 }
189 ret
190 }
191}
192
Alex Crichton954046c2017-05-30 21:49:42 -0700193impl<'a, T, D> IntoIterator for &'a Delimited<T, D> {
194 type Item = Element<&'a T, &'a D>;
195 type IntoIter = Iter<'a, T, D>;
196
197 fn into_iter(self) -> Iter<'a, T, D> {
198 <Delimited<T, D>>::iter(self)
199 }
200}
201
202impl<T, D> IntoIterator for Delimited<T, D> {
203 type Item = Element<T, D>;
204 type IntoIter = IntoIter<T, D>;
205
206 fn into_iter(self) -> IntoIter<T, D> {
207 IntoIter { inner: self.inner.into_iter() }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700208 }
209}
210
211impl<T, D> Default for Delimited<T, D> {
212 fn default() -> Self {
213 Delimited::new()
214 }
215}
216
217pub struct Iter<'a, T: 'a, D: 'a> {
218 inner: slice::Iter<'a, (T, Option<D>)>,
219}
220
221impl<'a, T, D> Iterator for Iter<'a, T, D> {
222 type Item = Element<&'a T, &'a D>;
223
224 fn next(&mut self) -> Option<Element<&'a T, &'a D>> {
225 self.inner.next().map(|pair| {
226 match pair.1 {
227 Some(ref delimited) => Element::Delimited(&pair.0, delimited),
228 None => Element::End(&pair.0),
229 }
230 })
231 }
232}
233
Alex Crichton164c5332017-07-06 13:18:34 -0700234pub struct IterMut<'a, T: 'a, D: 'a> {
235 inner: slice::IterMut<'a, (T, Option<D>)>,
236}
237
238impl<'a, T, D> Iterator for IterMut<'a, T, D> {
239 type Item = Element<&'a mut T, &'a mut D>;
240
241 fn next(&mut self) -> Option<Element<&'a mut T, &'a mut D>> {
242 self.inner.next().map(|pair| {
243 match pair.1 {
244 Some(ref mut delimited) => Element::Delimited(&mut pair.0, delimited),
245 None => Element::End(&mut pair.0),
246 }
247 })
248 }
249}
250
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700251pub struct Items<'a, T: 'a, D: 'a> {
252 inner: slice::Iter<'a, (T, Option<D>)>,
253}
254
255impl<'a, T, D> Iterator for Items<'a, T, D> {
256 type Item = &'a T;
257
258 fn next(&mut self) -> Option<&'a T> {
259 self.inner.next().map(|pair| &pair.0)
260 }
261}
262
263pub struct IntoIter<T, D> {
264 inner: vec::IntoIter<(T, Option<D>)>,
265}
266
267impl<T, D> Iterator for IntoIter<T, D> {
268 type Item = Element<T, D>;
269
270 fn next(&mut self) -> Option<Element<T, D>> {
271 self.inner.next().map(|pair| {
272 match pair.1 {
273 Some(v) => Element::Delimited(pair.0, v),
274 None => Element::End(pair.0)
275 }
276 })
277 }
278}
279
280pub enum Element<T, D> {
281 Delimited(T, D),
282 End(T),
283}
284
285impl<T, D> Element<T, D> {
286 pub fn into_item(self) -> T {
287 match self {
288 Element::Delimited(t, _) |
289 Element::End(t) => t,
290 }
291 }
292
293 pub fn item(&self) -> &T {
294 match *self {
295 Element::Delimited(ref t, _) |
296 Element::End(ref t) => t,
297 }
298 }
299
300 pub fn item_mut(&mut self) -> &mut T {
301 match *self {
302 Element::Delimited(ref mut t, _) |
303 Element::End(ref mut t) => t,
304 }
305 }
306
307 pub fn delimiter(&self) -> Option<&D> {
308 match *self {
309 Element::Delimited(_, ref d) => Some(d),
310 Element::End(_) => None,
311 }
312 }
313}
314
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700315#[cfg(feature = "parsing")]
316mod parsing {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700317 use super::Delimited;
Michael Layzell760fd662017-05-31 22:46:05 -0400318 use {PResult, Cursor, Synom, parse_error};
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700319
320 impl<T, D> Delimited<T, D>
321 where T: Synom,
322 D: Synom,
323 {
Michael Layzell760fd662017-05-31 22:46:05 -0400324 pub fn parse_separated(input: Cursor) -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700325 {
Alex Crichton954046c2017-05-30 21:49:42 -0700326 Self::parse(input, T::parse, false)
327 }
328
Michael Layzell760fd662017-05-31 22:46:05 -0400329 pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700330 {
331 Self::parse_separated_nonempty_with(input, T::parse)
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700332 }
333
Michael Layzell760fd662017-05-31 22:46:05 -0400334 pub fn parse_terminated(input: Cursor) -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700335 {
Alex Crichton954046c2017-05-30 21:49:42 -0700336 Self::parse_terminated_with(input, T::parse)
337 }
338 }
339
340 impl<T, D> Delimited<T, D>
341 where D: Synom,
342 {
343 pub fn parse_separated_nonempty_with(
Michael Layzell760fd662017-05-31 22:46:05 -0400344 input: Cursor,
345 parse: fn(Cursor) -> PResult<T>)
346 -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700347 {
348 match Self::parse(input, parse, false) {
Michael Layzell760fd662017-05-31 22:46:05 -0400349 Ok((_, ref b)) if b.is_empty() => parse_error(),
Alex Crichton954046c2017-05-30 21:49:42 -0700350 other => other,
351 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700352 }
353
Alex Crichton954046c2017-05-30 21:49:42 -0700354 pub fn parse_terminated_with(
Michael Layzell760fd662017-05-31 22:46:05 -0400355 input: Cursor,
356 parse: fn(Cursor) -> PResult<T>)
357 -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700358 {
359 Self::parse(input, parse, true)
360 }
361
Michael Layzell760fd662017-05-31 22:46:05 -0400362 fn parse(mut input: Cursor,
363 parse: fn(Cursor) -> PResult<T>,
Alex Crichton954046c2017-05-30 21:49:42 -0700364 terminated: bool)
Michael Layzell760fd662017-05-31 22:46:05 -0400365 -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700366 {
367 let mut res = Delimited::new();
368
369 // get the first element
Alex Crichton954046c2017-05-30 21:49:42 -0700370 match parse(input) {
Michael Layzell760fd662017-05-31 22:46:05 -0400371 Err(_) => Ok((input, res)),
372 Ok((i, o)) => {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400373 if i == input {
Michael Layzell760fd662017-05-31 22:46:05 -0400374 return parse_error();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700375 }
376 input = i;
377 res.push_first(o);
378
379 // get the separator first
Michael Layzell760fd662017-05-31 22:46:05 -0400380 while let Ok((i2, s)) = D::parse(input) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400381 if i2 == input {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700382 break;
383 }
384
385 // get the element next
Michael Layzell760fd662017-05-31 22:46:05 -0400386 if let Ok((i3, o3)) = parse(i2) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400387 if i3 == i2 {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700388 break;
389 }
390 res.push_next(o3, s);
391 input = i3;
392 } else {
393 break;
394 }
395 }
396 if terminated {
Michael Layzell760fd662017-05-31 22:46:05 -0400397 if let Ok((after, sep)) = D::parse(input) {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700398 res.push_trailing(sep);
399 input = after;
400 }
401 }
Michael Layzell760fd662017-05-31 22:46:05 -0400402 Ok((input, res))
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700403 }
404 }
405 }
406 }
407}
408
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700409#[cfg(feature = "printing")]
410mod printing {
411 use super::*;
412 use quote::{Tokens, ToTokens};
413
414
415 impl<T, D> ToTokens for Delimited<T, D>
416 where T: ToTokens,
417 D: ToTokens,
418 {
419 fn to_tokens(&self, tokens: &mut Tokens) {
420 tokens.append_all(self.iter())
421 }
422 }
423
424 impl<T, D> ToTokens for Element<T, D>
425 where T: ToTokens,
426 D: ToTokens,
427 {
428 fn to_tokens(&self, tokens: &mut Tokens) {
429 match *self {
430 Element::Delimited(ref a, ref b) => {
431 a.to_tokens(tokens);
432 b.to_tokens(tokens);
433 }
434 Element::End(ref a) => a.to_tokens(tokens),
435 }
436 }
437 }
438}