blob: 31f445c1be4af9f4553ca9a8959efa6220c4ff40 [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
42 pub fn iter(&self) -> Iter<T, D> {
43 Iter { inner: self.inner.iter() }
44 }
45
Alex Crichtonccbb45d2017-05-23 10:58:24 -070046 pub fn items(&self) -> Items<T, D> {
47 Items { inner: self.inner.iter() }
48 }
49
50 pub fn push(&mut self, token: Element<T, D>) {
Alex Crichton954046c2017-05-30 21:49:42 -070051 assert!(self.is_empty() || self.trailing_delim());
Alex Crichtonccbb45d2017-05-23 10:58:24 -070052 match token {
53 Element::Delimited(t, d) => self.inner.push((t, Some(d))),
54 Element::End(t) => self.inner.push((t, None)),
55 }
56 }
57
58 pub fn push_first(&mut self, token: T) {
59 assert!(self.is_empty());
60 self.inner.push((token, None));
61 }
62
63 pub fn push_next(&mut self, token: T, delimiter: D) {
64 self.push_trailing(delimiter);
65 self.inner.push((token, None));
66 }
67
68 pub fn push_trailing(&mut self, delimiter: D) {
69 let len = self.len();
70 assert!(self.inner[len - 1].1.is_none());
71 self.inner[len - 1].1 = Some(delimiter);
72 }
73
74 pub fn push_default(&mut self, token: T) where D: Default {
Alex Crichton954046c2017-05-30 21:49:42 -070075 if self.is_empty() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070076 self.inner.push((token, None));
77 } else {
78 self.push_next(token, D::default());
79 }
80 }
81
82 pub fn pop(&mut self) -> Option<Element<T, D>> {
83 self.inner.pop().map(|e| {
84 match e {
85 (t, Some(d)) => Element::Delimited(t, d),
86 (t, None) => Element::End(t),
87 }
88 })
89 }
90
91 pub fn into_vec(self) -> Vec<T> {
92 self.inner.into_iter().map(|t| t.0).collect()
93 }
94
95 pub fn trailing_delim(&self) -> bool {
96 self.inner[self.inner.len() - 1].1.is_some()
97 }
98}
99
100impl<T, D> From<Vec<(T, Option<D>)>> for Delimited<T, D> {
101 fn from(v: Vec<(T, Option<D>)>) -> Self {
102 Delimited {
103 inner: v,
104 }
105 }
106}
107
108impl<T, D> From<Vec<T>> for Delimited<T, D>
109 where D: Default,
110{
111 fn from(v: Vec<T>) -> Self {
112 let last = v.len() - 1;
113 Delimited {
114 inner: v.into_iter().enumerate().map(|(i, item)| {
115 (item, if i == last {None} else {Some(D::default())})
116 }).collect(),
117 }
118 }
119}
120
121impl<T, D> FromIterator<Element<T, D>> for Delimited<T, D> {
122 fn from_iter<I: IntoIterator<Item = Element<T, D>>>(i: I) -> Self {
123 let mut ret = Delimited::new();
124 for element in i {
125 match element {
126 Element::Delimited(a, b) => ret.inner.push((a, Some(b))),
127 Element::End(a) => ret.inner.push((a, None)),
128 }
129 }
Alex Crichton954046c2017-05-30 21:49:42 -0700130 ret
131 }
132}
133
134impl<'a, T, D> IntoIterator for &'a Delimited<T, D> {
135 type Item = Element<&'a T, &'a D>;
136 type IntoIter = Iter<'a, T, D>;
137
138 fn into_iter(self) -> Iter<'a, T, D> {
139 <Delimited<T, D>>::iter(self)
140 }
141}
142
143impl<T, D> IntoIterator for Delimited<T, D> {
144 type Item = Element<T, D>;
145 type IntoIter = IntoIter<T, D>;
146
147 fn into_iter(self) -> IntoIter<T, D> {
148 IntoIter { inner: self.inner.into_iter() }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700149 }
150}
151
152impl<T, D> Default for Delimited<T, D> {
153 fn default() -> Self {
154 Delimited::new()
155 }
156}
157
158pub struct Iter<'a, T: 'a, D: 'a> {
159 inner: slice::Iter<'a, (T, Option<D>)>,
160}
161
162impl<'a, T, D> Iterator for Iter<'a, T, D> {
163 type Item = Element<&'a T, &'a D>;
164
165 fn next(&mut self) -> Option<Element<&'a T, &'a D>> {
166 self.inner.next().map(|pair| {
167 match pair.1 {
168 Some(ref delimited) => Element::Delimited(&pair.0, delimited),
169 None => Element::End(&pair.0),
170 }
171 })
172 }
173}
174
175pub struct Items<'a, T: 'a, D: 'a> {
176 inner: slice::Iter<'a, (T, Option<D>)>,
177}
178
179impl<'a, T, D> Iterator for Items<'a, T, D> {
180 type Item = &'a T;
181
182 fn next(&mut self) -> Option<&'a T> {
183 self.inner.next().map(|pair| &pair.0)
184 }
185}
186
187pub struct IntoIter<T, D> {
188 inner: vec::IntoIter<(T, Option<D>)>,
189}
190
191impl<T, D> Iterator for IntoIter<T, D> {
192 type Item = Element<T, D>;
193
194 fn next(&mut self) -> Option<Element<T, D>> {
195 self.inner.next().map(|pair| {
196 match pair.1 {
197 Some(v) => Element::Delimited(pair.0, v),
198 None => Element::End(pair.0)
199 }
200 })
201 }
202}
203
204pub enum Element<T, D> {
205 Delimited(T, D),
206 End(T),
207}
208
209impl<T, D> Element<T, D> {
210 pub fn into_item(self) -> T {
211 match self {
212 Element::Delimited(t, _) |
213 Element::End(t) => t,
214 }
215 }
216
217 pub fn item(&self) -> &T {
218 match *self {
219 Element::Delimited(ref t, _) |
220 Element::End(ref t) => t,
221 }
222 }
223
224 pub fn item_mut(&mut self) -> &mut T {
225 match *self {
226 Element::Delimited(ref mut t, _) |
227 Element::End(ref mut t) => t,
228 }
229 }
230
231 pub fn delimiter(&self) -> Option<&D> {
232 match *self {
233 Element::Delimited(_, ref d) => Some(d),
234 Element::End(_) => None,
235 }
236 }
237}
238
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700239#[cfg(feature = "parsing")]
240mod parsing {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700241 use super::Delimited;
Michael Layzell760fd662017-05-31 22:46:05 -0400242 use {PResult, Cursor, Synom, parse_error};
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700243
244 impl<T, D> Delimited<T, D>
245 where T: Synom,
246 D: Synom,
247 {
Michael Layzell760fd662017-05-31 22:46:05 -0400248 pub fn parse_separated(input: Cursor) -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700249 {
Alex Crichton954046c2017-05-30 21:49:42 -0700250 Self::parse(input, T::parse, false)
251 }
252
Michael Layzell760fd662017-05-31 22:46:05 -0400253 pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700254 {
255 Self::parse_separated_nonempty_with(input, T::parse)
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700256 }
257
Michael Layzell760fd662017-05-31 22:46:05 -0400258 pub fn parse_terminated(input: Cursor) -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700259 {
Alex Crichton954046c2017-05-30 21:49:42 -0700260 Self::parse_terminated_with(input, T::parse)
261 }
262 }
263
264 impl<T, D> Delimited<T, D>
265 where D: Synom,
266 {
267 pub fn parse_separated_nonempty_with(
Michael Layzell760fd662017-05-31 22:46:05 -0400268 input: Cursor,
269 parse: fn(Cursor) -> PResult<T>)
270 -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700271 {
272 match Self::parse(input, parse, false) {
Michael Layzell760fd662017-05-31 22:46:05 -0400273 Ok((_, ref b)) if b.is_empty() => parse_error(),
Alex Crichton954046c2017-05-30 21:49:42 -0700274 other => other,
275 }
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700276 }
277
Alex Crichton954046c2017-05-30 21:49:42 -0700278 pub fn parse_terminated_with(
Michael Layzell760fd662017-05-31 22:46:05 -0400279 input: Cursor,
280 parse: fn(Cursor) -> PResult<T>)
281 -> PResult<Self>
Alex Crichton954046c2017-05-30 21:49:42 -0700282 {
283 Self::parse(input, parse, true)
284 }
285
Michael Layzell760fd662017-05-31 22:46:05 -0400286 fn parse(mut input: Cursor,
287 parse: fn(Cursor) -> PResult<T>,
Alex Crichton954046c2017-05-30 21:49:42 -0700288 terminated: bool)
Michael Layzell760fd662017-05-31 22:46:05 -0400289 -> PResult<Self>
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700290 {
291 let mut res = Delimited::new();
292
293 // get the first element
Alex Crichton954046c2017-05-30 21:49:42 -0700294 match parse(input) {
Michael Layzell760fd662017-05-31 22:46:05 -0400295 Err(_) => Ok((input, res)),
296 Ok((i, o)) => {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400297 if i == input {
Michael Layzell760fd662017-05-31 22:46:05 -0400298 return parse_error();
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700299 }
300 input = i;
301 res.push_first(o);
302
303 // get the separator first
Michael Layzell760fd662017-05-31 22:46:05 -0400304 while let Ok((i2, s)) = D::parse(input) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400305 if i2 == input {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700306 break;
307 }
308
309 // get the element next
Michael Layzell760fd662017-05-31 22:46:05 -0400310 if let Ok((i3, o3)) = parse(i2) {
Michael Layzell0a1a6632017-06-02 18:07:43 -0400311 if i3 == i2 {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700312 break;
313 }
314 res.push_next(o3, s);
315 input = i3;
316 } else {
317 break;
318 }
319 }
320 if terminated {
Michael Layzell760fd662017-05-31 22:46:05 -0400321 if let Ok((after, sep)) = D::parse(input) {
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700322 res.push_trailing(sep);
323 input = after;
324 }
325 }
Michael Layzell760fd662017-05-31 22:46:05 -0400326 Ok((input, res))
Alex Crichton7b9e02f2017-05-30 15:54:33 -0700327 }
328 }
329 }
330 }
331}
332
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700333#[cfg(feature = "printing")]
334mod printing {
335 use super::*;
336 use quote::{Tokens, ToTokens};
337
338
339 impl<T, D> ToTokens for Delimited<T, D>
340 where T: ToTokens,
341 D: ToTokens,
342 {
343 fn to_tokens(&self, tokens: &mut Tokens) {
344 tokens.append_all(self.iter())
345 }
346 }
347
348 impl<T, D> ToTokens for Element<T, D>
349 where T: ToTokens,
350 D: ToTokens,
351 {
352 fn to_tokens(&self, tokens: &mut Tokens) {
353 match *self {
354 Element::Delimited(ref a, ref b) => {
355 a.to_tokens(tokens);
356 b.to_tokens(tokens);
357 }
358 Element::End(ref a) => a.to_tokens(tokens),
359 }
360 }
361 }
362}