1 //! A punctuated sequence of syntax tree nodes separated by punctuation. 2 //! 3 //! Lots of things in Rust are punctuated sequences. 4 //! 5 //! - The fields of a struct are `Punctuated<Field, Token![,]>`. 6 //! - The segments of a path are `Punctuated<PathSegment, Token![::]>`. 7 //! - The bounds on a generic parameter are `Punctuated<TypeParamBound, 8 //! Token![+]>`. 9 //! - The arguments to a function call are `Punctuated<Expr, Token![,]>`. 10 //! 11 //! This module provides a common representation for these punctuated sequences 12 //! in the form of the [`Punctuated<T, P>`] type. We store a vector of pairs of 13 //! syntax tree node + punctuation, where every node in the sequence is followed 14 //! by punctuation except for possibly the final one. 15 //! 16 //! [`Punctuated<T, P>`]: struct.Punctuated.html 17 //! 18 //! ```text 19 //! a_function_call(arg1, arg2, arg3); 20 //! ^^^^^ ~~~~~ ^^^^ 21 //! ``` 22 23 #[cfg(feature = "extra-traits")] 24 use std::fmt::{self, Debug}; 25 #[cfg(any(feature = "full", feature = "derive"))] 26 use std::iter; 27 use std::iter::FromIterator; 28 use std::ops::{Index, IndexMut}; 29 use std::option; 30 use std::slice; 31 use std::vec; 32 33 #[cfg(feature = "parsing")] 34 use parse::{Parse, ParseStream, Result}; 35 #[cfg(any(feature = "full", feature = "derive"))] 36 use private; 37 #[cfg(feature = "parsing")] 38 use token::Token; 39 40 /// A punctuated sequence of syntax tree nodes of type `T` separated by 41 /// punctuation of type `P`. 42 /// 43 /// Refer to the [module documentation] for details about punctuated sequences. 44 /// 45 /// [module documentation]: index.html 46 #[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))] 47 #[cfg_attr(feature = "clone-impls", derive(Clone))] 48 pub struct Punctuated<T, P> { 49 inner: Vec<(T, P)>, 50 last: Option<Box<T>>, 51 } 52 53 impl<T, P> Punctuated<T, P> { 54 /// Creates an empty punctuated sequence. new() -> Punctuated<T, P>55 pub fn new() -> Punctuated<T, P> { 56 Punctuated { 57 inner: Vec::new(), 58 last: None, 59 } 60 } 61 62 /// Determines whether this punctuated sequence is empty, meaning it 63 /// contains no syntax tree nodes or punctuation. is_empty(&self) -> bool64 pub fn is_empty(&self) -> bool { 65 self.inner.len() == 0 && self.last.is_none() 66 } 67 68 /// Returns the number of syntax tree nodes in this punctuated sequence. 69 /// 70 /// This is the number of nodes of type `T`, not counting the punctuation of 71 /// type `P`. len(&self) -> usize72 pub fn len(&self) -> usize { 73 self.inner.len() + if self.last.is_some() { 1 } else { 0 } 74 } 75 76 /// Borrows the first punctuated pair in this sequence. first(&self) -> Option<Pair<&T, &P>>77 pub fn first(&self) -> Option<Pair<&T, &P>> { 78 self.pairs().next() 79 } 80 81 /// Borrows the last punctuated pair in this sequence. last(&self) -> Option<Pair<&T, &P>>82 pub fn last(&self) -> Option<Pair<&T, &P>> { 83 if self.last.is_some() { 84 self.last.as_ref().map(|t| Pair::End(t.as_ref())) 85 } else { 86 self.inner 87 .last() 88 .map(|&(ref t, ref d)| Pair::Punctuated(t, d)) 89 } 90 } 91 92 /// Mutably borrows the last punctuated pair in this sequence. last_mut(&mut self) -> Option<Pair<&mut T, &mut P>>93 pub fn last_mut(&mut self) -> Option<Pair<&mut T, &mut P>> { 94 if self.last.is_some() { 95 self.last.as_mut().map(|t| Pair::End(t.as_mut())) 96 } else { 97 self.inner 98 .last_mut() 99 .map(|&mut (ref mut t, ref mut d)| Pair::Punctuated(t, d)) 100 } 101 } 102 103 /// Returns an iterator over borrowed syntax tree nodes of type `&T`. iter(&self) -> Iter<T>104 pub fn iter(&self) -> Iter<T> { 105 Iter { 106 inner: Box::new(PrivateIter { 107 inner: self.inner.iter(), 108 last: self.last.as_ref().map(Box::as_ref).into_iter(), 109 }), 110 } 111 } 112 113 /// Returns an iterator over mutably borrowed syntax tree nodes of type 114 /// `&mut T`. iter_mut(&mut self) -> IterMut<T>115 pub fn iter_mut(&mut self) -> IterMut<T> { 116 IterMut { 117 inner: Box::new(PrivateIterMut { 118 inner: self.inner.iter_mut(), 119 last: self.last.as_mut().map(Box::as_mut).into_iter(), 120 }), 121 } 122 } 123 124 /// Returns an iterator over the contents of this sequence as borrowed 125 /// punctuated pairs. pairs(&self) -> Pairs<T, P>126 pub fn pairs(&self) -> Pairs<T, P> { 127 Pairs { 128 inner: self.inner.iter(), 129 last: self.last.as_ref().map(Box::as_ref).into_iter(), 130 } 131 } 132 133 /// Returns an iterator over the contents of this sequence as mutably 134 /// borrowed punctuated pairs. pairs_mut(&mut self) -> PairsMut<T, P>135 pub fn pairs_mut(&mut self) -> PairsMut<T, P> { 136 PairsMut { 137 inner: self.inner.iter_mut(), 138 last: self.last.as_mut().map(Box::as_mut).into_iter(), 139 } 140 } 141 142 /// Returns an iterator over the contents of this sequence as owned 143 /// punctuated pairs. into_pairs(self) -> IntoPairs<T, P>144 pub fn into_pairs(self) -> IntoPairs<T, P> { 145 IntoPairs { 146 inner: self.inner.into_iter(), 147 last: self.last.map(|t| *t).into_iter(), 148 } 149 } 150 151 /// Appends a syntax tree node onto the end of this punctuated sequence. The 152 /// sequence must previously have a trailing punctuation. 153 /// 154 /// Use [`push`] instead if the punctuated sequence may or may not already 155 /// have trailing punctuation. 156 /// 157 /// [`push`]: #method.push 158 /// 159 /// # Panics 160 /// 161 /// Panics if the sequence does not already have a trailing punctuation when 162 /// this method is called. push_value(&mut self, value: T)163 pub fn push_value(&mut self, value: T) { 164 assert!(self.empty_or_trailing()); 165 self.last = Some(Box::new(value)); 166 } 167 168 /// Appends a trailing punctuation onto the end of this punctuated sequence. 169 /// The sequence must be non-empty and must not already have trailing 170 /// punctuation. 171 /// 172 /// # Panics 173 /// 174 /// Panics if the sequence is empty or already has a trailing punctuation. push_punct(&mut self, punctuation: P)175 pub fn push_punct(&mut self, punctuation: P) { 176 assert!(self.last.is_some()); 177 let last = self.last.take().unwrap(); 178 self.inner.push((*last, punctuation)); 179 } 180 181 /// Removes the last punctuated pair from this sequence, or `None` if the 182 /// sequence is empty. pop(&mut self) -> Option<Pair<T, P>>183 pub fn pop(&mut self) -> Option<Pair<T, P>> { 184 if self.last.is_some() { 185 self.last.take().map(|t| Pair::End(*t)) 186 } else { 187 self.inner.pop().map(|(t, d)| Pair::Punctuated(t, d)) 188 } 189 } 190 191 /// Determines whether this punctuated sequence ends with a trailing 192 /// punctuation. trailing_punct(&self) -> bool193 pub fn trailing_punct(&self) -> bool { 194 self.last.is_none() && !self.is_empty() 195 } 196 197 /// Returns true if either this `Punctuated` is empty, or it has a trailing 198 /// punctuation. 199 /// 200 /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`. empty_or_trailing(&self) -> bool201 pub fn empty_or_trailing(&self) -> bool { 202 self.last.is_none() 203 } 204 205 /// Appends a syntax tree node onto the end of this punctuated sequence. 206 /// 207 /// If there is not a trailing punctuation in this sequence when this method 208 /// is called, the default value of punctuation type `P` is inserted before 209 /// the given value of type `T`. push(&mut self, value: T) where P: Default,210 pub fn push(&mut self, value: T) 211 where 212 P: Default, 213 { 214 if !self.empty_or_trailing() { 215 self.push_punct(Default::default()); 216 } 217 self.push_value(value); 218 } 219 220 /// Inserts an element at position `index`. 221 /// 222 /// # Panics 223 /// 224 /// Panics if `index` is greater than the number of elements previously in 225 /// this punctuated sequence. insert(&mut self, index: usize, value: T) where P: Default,226 pub fn insert(&mut self, index: usize, value: T) 227 where 228 P: Default, 229 { 230 assert!(index <= self.len()); 231 232 if index == self.len() { 233 self.push(value); 234 } else { 235 self.inner.insert(index, (value, Default::default())); 236 } 237 } 238 239 /// Parses zero or more occurrences of `T` separated by punctuation of type 240 /// `P`, with optional trailing punctuation. 241 /// 242 /// Parsing continues until the end of this parse stream. The entire content 243 /// of this parse stream must consist of `T` and `P`. 244 /// 245 /// *This function is available if Syn is built with the `"parsing"` 246 /// feature.* 247 #[cfg(feature = "parsing")] parse_terminated(input: ParseStream) -> Result<Self> where T: Parse, P: Parse,248 pub fn parse_terminated(input: ParseStream) -> Result<Self> 249 where 250 T: Parse, 251 P: Parse, 252 { 253 Self::parse_terminated_with(input, T::parse) 254 } 255 256 /// Parses zero or more occurrences of `T` using the given parse function, 257 /// separated by punctuation of type `P`, with optional trailing 258 /// punctuation. 259 /// 260 /// Like [`parse_terminated`], the entire content of this stream is expected 261 /// to be parsed. 262 /// 263 /// [`parse_terminated`]: #method.parse_terminated 264 /// 265 /// *This function is available if Syn is built with the `"parsing"` 266 /// feature.* 267 #[cfg(feature = "parsing")] parse_terminated_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Parse,268 pub fn parse_terminated_with( 269 input: ParseStream, 270 parser: fn(ParseStream) -> Result<T>, 271 ) -> Result<Self> 272 where 273 P: Parse, 274 { 275 let mut punctuated = Punctuated::new(); 276 277 loop { 278 if input.is_empty() { 279 break; 280 } 281 let value = parser(input)?; 282 punctuated.push_value(value); 283 if input.is_empty() { 284 break; 285 } 286 let punct = input.parse()?; 287 punctuated.push_punct(punct); 288 } 289 290 Ok(punctuated) 291 } 292 293 /// Parses one or more occurrences of `T` separated by punctuation of type 294 /// `P`, not accepting trailing punctuation. 295 /// 296 /// Parsing continues as long as punctuation `P` is present at the head of 297 /// the stream. This method returns upon parsing a `T` and observing that it 298 /// is not followed by a `P`, even if there are remaining tokens in the 299 /// stream. 300 /// 301 /// *This function is available if Syn is built with the `"parsing"` 302 /// feature.* 303 #[cfg(feature = "parsing")] parse_separated_nonempty(input: ParseStream) -> Result<Self> where T: Parse, P: Token + Parse,304 pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self> 305 where 306 T: Parse, 307 P: Token + Parse, 308 { 309 Self::parse_separated_nonempty_with(input, T::parse) 310 } 311 312 /// Parses one or more occurrences of `T` using the given parse function, 313 /// separated by punctuation of type `P`, not accepting trailing 314 /// punctuation. 315 /// 316 /// Like [`parse_separated_nonempty`], may complete early without parsing 317 /// the entire content of this stream. 318 /// 319 /// [`parse_separated_nonempty`]: #method.parse_separated_nonempty 320 /// 321 /// *This function is available if Syn is built with the `"parsing"` 322 /// feature.* 323 #[cfg(feature = "parsing")] parse_separated_nonempty_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Token + Parse,324 pub fn parse_separated_nonempty_with( 325 input: ParseStream, 326 parser: fn(ParseStream) -> Result<T>, 327 ) -> Result<Self> 328 where 329 P: Token + Parse, 330 { 331 let mut punctuated = Punctuated::new(); 332 333 loop { 334 let value = parser(input)?; 335 punctuated.push_value(value); 336 if !P::peek(input.cursor()) { 337 break; 338 } 339 let punct = input.parse()?; 340 punctuated.push_punct(punct); 341 } 342 343 Ok(punctuated) 344 } 345 } 346 347 #[cfg(feature = "extra-traits")] 348 impl<T: Debug, P: Debug> Debug for Punctuated<T, P> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result349 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 350 let mut list = f.debug_list(); 351 for &(ref t, ref p) in &self.inner { 352 list.entry(t); 353 list.entry(p); 354 } 355 if let Some(ref last) = self.last { 356 list.entry(last); 357 } 358 list.finish() 359 } 360 } 361 362 impl<T, P> FromIterator<T> for Punctuated<T, P> 363 where 364 P: Default, 365 { from_iter<I: IntoIterator<Item = T>>(i: I) -> Self366 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self { 367 let mut ret = Punctuated::new(); 368 ret.extend(i); 369 ret 370 } 371 } 372 373 impl<T, P> Extend<T> for Punctuated<T, P> 374 where 375 P: Default, 376 { extend<I: IntoIterator<Item = T>>(&mut self, i: I)377 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) { 378 for value in i { 379 self.push(value); 380 } 381 } 382 } 383 384 impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> { from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self385 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self { 386 let mut ret = Punctuated::new(); 387 ret.extend(i); 388 ret 389 } 390 } 391 392 impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> { extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I)393 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) { 394 assert!(self.empty_or_trailing()); 395 let mut nomore = false; 396 for pair in i { 397 if nomore { 398 panic!("Punctuated extended with items after a Pair::End"); 399 } 400 match pair { 401 Pair::Punctuated(a, b) => self.inner.push((a, b)), 402 Pair::End(a) => { 403 self.last = Some(Box::new(a)); 404 nomore = true; 405 } 406 } 407 } 408 } 409 } 410 411 impl<T, P> IntoIterator for Punctuated<T, P> { 412 type Item = T; 413 type IntoIter = IntoIter<T, P>; 414 into_iter(self) -> Self::IntoIter415 fn into_iter(self) -> Self::IntoIter { 416 IntoIter { 417 inner: self.inner.into_iter(), 418 last: self.last.map(|t| *t).into_iter(), 419 } 420 } 421 } 422 423 impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> { 424 type Item = &'a T; 425 type IntoIter = Iter<'a, T>; 426 into_iter(self) -> Self::IntoIter427 fn into_iter(self) -> Self::IntoIter { 428 Punctuated::iter(self) 429 } 430 } 431 432 impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> { 433 type Item = &'a mut T; 434 type IntoIter = IterMut<'a, T>; 435 into_iter(self) -> Self::IntoIter436 fn into_iter(self) -> Self::IntoIter { 437 Punctuated::iter_mut(self) 438 } 439 } 440 441 impl<T, P> Default for Punctuated<T, P> { default() -> Self442 fn default() -> Self { 443 Punctuated::new() 444 } 445 } 446 447 /// An iterator over borrowed pairs of type `Pair<&T, &P>`. 448 /// 449 /// Refer to the [module documentation] for details about punctuated sequences. 450 /// 451 /// [module documentation]: index.html 452 pub struct Pairs<'a, T: 'a, P: 'a> { 453 inner: slice::Iter<'a, (T, P)>, 454 last: option::IntoIter<&'a T>, 455 } 456 457 impl<'a, T, P> Iterator for Pairs<'a, T, P> { 458 type Item = Pair<&'a T, &'a P>; 459 next(&mut self) -> Option<Self::Item>460 fn next(&mut self) -> Option<Self::Item> { 461 self.inner 462 .next() 463 .map(|&(ref t, ref p)| Pair::Punctuated(t, p)) 464 .or_else(|| self.last.next().map(Pair::End)) 465 } 466 } 467 468 impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> { len(&self) -> usize469 fn len(&self) -> usize { 470 self.inner.len() + self.last.len() 471 } 472 } 473 474 /// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`. 475 /// 476 /// Refer to the [module documentation] for details about punctuated sequences. 477 /// 478 /// [module documentation]: index.html 479 pub struct PairsMut<'a, T: 'a, P: 'a> { 480 inner: slice::IterMut<'a, (T, P)>, 481 last: option::IntoIter<&'a mut T>, 482 } 483 484 impl<'a, T, P> Iterator for PairsMut<'a, T, P> { 485 type Item = Pair<&'a mut T, &'a mut P>; 486 next(&mut self) -> Option<Self::Item>487 fn next(&mut self) -> Option<Self::Item> { 488 self.inner 489 .next() 490 .map(|&mut (ref mut t, ref mut p)| Pair::Punctuated(t, p)) 491 .or_else(|| self.last.next().map(Pair::End)) 492 } 493 } 494 495 impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> { len(&self) -> usize496 fn len(&self) -> usize { 497 self.inner.len() + self.last.len() 498 } 499 } 500 501 /// An iterator over owned pairs of type `Pair<T, P>`. 502 /// 503 /// Refer to the [module documentation] for details about punctuated sequences. 504 /// 505 /// [module documentation]: index.html 506 pub struct IntoPairs<T, P> { 507 inner: vec::IntoIter<(T, P)>, 508 last: option::IntoIter<T>, 509 } 510 511 impl<T, P> Iterator for IntoPairs<T, P> { 512 type Item = Pair<T, P>; 513 next(&mut self) -> Option<Self::Item>514 fn next(&mut self) -> Option<Self::Item> { 515 self.inner 516 .next() 517 .map(|(t, p)| Pair::Punctuated(t, p)) 518 .or_else(|| self.last.next().map(Pair::End)) 519 } 520 } 521 522 impl<T, P> ExactSizeIterator for IntoPairs<T, P> { len(&self) -> usize523 fn len(&self) -> usize { 524 self.inner.len() + self.last.len() 525 } 526 } 527 528 /// An iterator over owned values of type `T`. 529 /// 530 /// Refer to the [module documentation] for details about punctuated sequences. 531 /// 532 /// [module documentation]: index.html 533 pub struct IntoIter<T, P> { 534 inner: vec::IntoIter<(T, P)>, 535 last: option::IntoIter<T>, 536 } 537 538 impl<T, P> Iterator for IntoIter<T, P> { 539 type Item = T; 540 next(&mut self) -> Option<Self::Item>541 fn next(&mut self) -> Option<Self::Item> { 542 self.inner 543 .next() 544 .map(|pair| pair.0) 545 .or_else(|| self.last.next()) 546 } 547 } 548 549 impl<T, P> ExactSizeIterator for IntoIter<T, P> { len(&self) -> usize550 fn len(&self) -> usize { 551 self.inner.len() + self.last.len() 552 } 553 } 554 555 /// An iterator over borrowed values of type `&T`. 556 /// 557 /// Refer to the [module documentation] for details about punctuated sequences. 558 /// 559 /// [module documentation]: index.html 560 pub struct Iter<'a, T: 'a> { 561 inner: Box<ExactSizeIterator<Item = &'a T> + 'a>, 562 } 563 564 struct PrivateIter<'a, T: 'a, P: 'a> { 565 inner: slice::Iter<'a, (T, P)>, 566 last: option::IntoIter<&'a T>, 567 } 568 569 #[cfg(any(feature = "full", feature = "derive"))] 570 impl private { empty_punctuated_iter<'a, T>() -> Iter<'a, T>571 pub fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> { 572 Iter { 573 inner: Box::new(iter::empty()), 574 } 575 } 576 } 577 578 impl<'a, T> Iterator for Iter<'a, T> { 579 type Item = &'a T; 580 next(&mut self) -> Option<Self::Item>581 fn next(&mut self) -> Option<Self::Item> { 582 self.inner.next() 583 } 584 } 585 586 impl<'a, T> ExactSizeIterator for Iter<'a, T> { len(&self) -> usize587 fn len(&self) -> usize { 588 self.inner.len() 589 } 590 } 591 592 impl<'a, T, P> Iterator for PrivateIter<'a, T, P> { 593 type Item = &'a T; 594 next(&mut self) -> Option<Self::Item>595 fn next(&mut self) -> Option<Self::Item> { 596 self.inner 597 .next() 598 .map(|pair| &pair.0) 599 .or_else(|| self.last.next()) 600 } 601 } 602 603 impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> { len(&self) -> usize604 fn len(&self) -> usize { 605 self.inner.len() + self.last.len() 606 } 607 } 608 609 /// An iterator over mutably borrowed values of type `&mut T`. 610 /// 611 /// Refer to the [module documentation] for details about punctuated sequences. 612 /// 613 /// [module documentation]: index.html 614 pub struct IterMut<'a, T: 'a> { 615 inner: Box<ExactSizeIterator<Item = &'a mut T> + 'a>, 616 } 617 618 struct PrivateIterMut<'a, T: 'a, P: 'a> { 619 inner: slice::IterMut<'a, (T, P)>, 620 last: option::IntoIter<&'a mut T>, 621 } 622 623 #[cfg(any(feature = "full", feature = "derive"))] 624 impl private { empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T>625 pub fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> { 626 IterMut { 627 inner: Box::new(iter::empty()), 628 } 629 } 630 } 631 632 impl<'a, T> Iterator for IterMut<'a, T> { 633 type Item = &'a mut T; 634 next(&mut self) -> Option<Self::Item>635 fn next(&mut self) -> Option<Self::Item> { 636 self.inner.next() 637 } 638 } 639 640 impl<'a, T> ExactSizeIterator for IterMut<'a, T> { len(&self) -> usize641 fn len(&self) -> usize { 642 self.inner.len() 643 } 644 } 645 646 impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> { 647 type Item = &'a mut T; 648 next(&mut self) -> Option<Self::Item>649 fn next(&mut self) -> Option<Self::Item> { 650 self.inner 651 .next() 652 .map(|pair| &mut pair.0) 653 .or_else(|| self.last.next()) 654 } 655 } 656 657 impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> { len(&self) -> usize658 fn len(&self) -> usize { 659 self.inner.len() + self.last.len() 660 } 661 } 662 663 /// A single syntax tree node of type `T` followed by its trailing punctuation 664 /// of type `P` if any. 665 /// 666 /// Refer to the [module documentation] for details about punctuated sequences. 667 /// 668 /// [module documentation]: index.html 669 pub enum Pair<T, P> { 670 Punctuated(T, P), 671 End(T), 672 } 673 674 impl<T, P> Pair<T, P> { 675 /// Extracts the syntax tree node from this punctuated pair, discarding the 676 /// following punctuation. into_value(self) -> T677 pub fn into_value(self) -> T { 678 match self { 679 Pair::Punctuated(t, _) | Pair::End(t) => t, 680 } 681 } 682 683 /// Borrows the syntax tree node from this punctuated pair. value(&self) -> &T684 pub fn value(&self) -> &T { 685 match *self { 686 Pair::Punctuated(ref t, _) | Pair::End(ref t) => t, 687 } 688 } 689 690 /// Mutably borrows the syntax tree node from this punctuated pair. value_mut(&mut self) -> &mut T691 pub fn value_mut(&mut self) -> &mut T { 692 match *self { 693 Pair::Punctuated(ref mut t, _) | Pair::End(ref mut t) => t, 694 } 695 } 696 697 /// Borrows the punctuation from this punctuated pair, unless this pair is 698 /// the final one and there is no trailing punctuation. punct(&self) -> Option<&P>699 pub fn punct(&self) -> Option<&P> { 700 match *self { 701 Pair::Punctuated(_, ref d) => Some(d), 702 Pair::End(_) => None, 703 } 704 } 705 706 /// Creates a punctuated pair out of a syntax tree node and an optional 707 /// following punctuation. new(t: T, d: Option<P>) -> Self708 pub fn new(t: T, d: Option<P>) -> Self { 709 match d { 710 Some(d) => Pair::Punctuated(t, d), 711 None => Pair::End(t), 712 } 713 } 714 715 /// Produces this punctuated pair as a tuple of syntax tree node and 716 /// optional following punctuation. into_tuple(self) -> (T, Option<P>)717 pub fn into_tuple(self) -> (T, Option<P>) { 718 match self { 719 Pair::Punctuated(t, d) => (t, Some(d)), 720 Pair::End(t) => (t, None), 721 } 722 } 723 } 724 725 impl<T, P> Index<usize> for Punctuated<T, P> { 726 type Output = T; 727 index(&self, index: usize) -> &Self::Output728 fn index(&self, index: usize) -> &Self::Output { 729 if index == self.len() - 1 { 730 match self.last { 731 Some(ref t) => t, 732 None => &self.inner[index].0, 733 } 734 } else { 735 &self.inner[index].0 736 } 737 } 738 } 739 740 impl<T, P> IndexMut<usize> for Punctuated<T, P> { index_mut(&mut self, index: usize) -> &mut Self::Output741 fn index_mut(&mut self, index: usize) -> &mut Self::Output { 742 if index == self.len() - 1 { 743 match self.last { 744 Some(ref mut t) => t, 745 None => &mut self.inner[index].0, 746 } 747 } else { 748 &mut self.inner[index].0 749 } 750 } 751 } 752 753 #[cfg(feature = "printing")] 754 mod printing { 755 use super::*; 756 use proc_macro2::TokenStream; 757 use quote::{ToTokens, TokenStreamExt}; 758 759 impl<T, P> ToTokens for Punctuated<T, P> 760 where 761 T: ToTokens, 762 P: ToTokens, 763 { to_tokens(&self, tokens: &mut TokenStream)764 fn to_tokens(&self, tokens: &mut TokenStream) { 765 tokens.append_all(self.pairs()) 766 } 767 } 768 769 impl<T, P> ToTokens for Pair<T, P> 770 where 771 T: ToTokens, 772 P: ToTokens, 773 { to_tokens(&self, tokens: &mut TokenStream)774 fn to_tokens(&self, tokens: &mut TokenStream) { 775 match *self { 776 Pair::Punctuated(ref a, ref b) => { 777 a.to_tokens(tokens); 778 b.to_tokens(tokens); 779 } 780 Pair::End(ref a) => a.to_tokens(tokens), 781 } 782 } 783 } 784 } 785