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>`]: Punctuated 17 //! 18 //! ```text 19 //! a_function_call(arg1, arg2, arg3); 20 //! ~~~~^ ~~~~^ ~~~~ 21 //! ``` 22 23 use crate::drops::{NoDrop, TrivialDrop}; 24 #[cfg(feature = "parsing")] 25 use crate::error::Result; 26 #[cfg(feature = "parsing")] 27 use crate::parse::{Parse, ParseStream}; 28 #[cfg(feature = "parsing")] 29 use crate::token::Token; 30 #[cfg(feature = "extra-traits")] 31 use std::fmt::{self, Debug}; 32 #[cfg(feature = "extra-traits")] 33 use std::hash::{Hash, Hasher}; 34 #[cfg(any(feature = "full", feature = "derive"))] 35 use std::iter; 36 use std::ops::{Index, IndexMut}; 37 use std::option; 38 use std::slice; 39 use std::vec; 40 41 /// **A punctuated sequence of syntax tree nodes of type `T` separated by 42 /// punctuation of type `P`.** 43 /// 44 /// Refer to the [module documentation] for details about punctuated sequences. 45 /// 46 /// [module documentation]: self 47 pub struct Punctuated<T, P> { 48 inner: Vec<(T, P)>, 49 last: Option<Box<T>>, 50 } 51 52 impl<T, P> Punctuated<T, P> { 53 /// Creates an empty punctuated sequence. 54 pub const fn new() -> Self { 55 Punctuated { 56 inner: Vec::new(), 57 last: None, 58 } 59 } 60 61 /// Determines whether this punctuated sequence is empty, meaning it 62 /// contains no syntax tree nodes or punctuation. 63 pub fn is_empty(&self) -> bool { 64 self.inner.len() == 0 && self.last.is_none() 65 } 66 67 /// Returns the number of syntax tree nodes in this punctuated sequence. 68 /// 69 /// This is the number of nodes of type `T`, not counting the punctuation of 70 /// type `P`. 71 pub fn len(&self) -> usize { 72 self.inner.len() + if self.last.is_some() { 1 } else { 0 } 73 } 74 75 /// Borrows the first element in this sequence. 76 pub fn first(&self) -> Option<&T> { 77 self.iter().next() 78 } 79 80 /// Mutably borrows the first element in this sequence. 81 pub fn first_mut(&mut self) -> Option<&mut T> { 82 self.iter_mut().next() 83 } 84 85 /// Borrows the last element in this sequence. 86 pub fn last(&self) -> Option<&T> { 87 self.iter().next_back() 88 } 89 90 /// Mutably borrows the last element in this sequence. 91 pub fn last_mut(&mut self) -> Option<&mut T> { 92 self.iter_mut().next_back() 93 } 94 95 /// Borrows the element at the given index. 96 pub fn get(&self, index: usize) -> Option<&T> { 97 if let Some((value, _punct)) = self.inner.get(index) { 98 Some(value) 99 } else if index == self.inner.len() { 100 self.last.as_deref() 101 } else { 102 None 103 } 104 } 105 106 /// Mutably borrows the element at the given index. 107 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { 108 let inner_len = self.inner.len(); 109 if let Some((value, _punct)) = self.inner.get_mut(index) { 110 Some(value) 111 } else if index == inner_len { 112 self.last.as_deref_mut() 113 } else { 114 None 115 } 116 } 117 118 /// Returns an iterator over borrowed syntax tree nodes of type `&T`. 119 pub fn iter(&self) -> Iter<T> { 120 Iter { 121 inner: Box::new(NoDrop::new(PrivateIter { 122 inner: self.inner.iter(), 123 last: self.last.as_ref().map(Box::as_ref).into_iter(), 124 })), 125 } 126 } 127 128 /// Returns an iterator over mutably borrowed syntax tree nodes of type 129 /// `&mut T`. 130 pub fn iter_mut(&mut self) -> IterMut<T> { 131 IterMut { 132 inner: Box::new(NoDrop::new(PrivateIterMut { 133 inner: self.inner.iter_mut(), 134 last: self.last.as_mut().map(Box::as_mut).into_iter(), 135 })), 136 } 137 } 138 139 /// Returns an iterator over the contents of this sequence as borrowed 140 /// punctuated pairs. 141 pub fn pairs(&self) -> Pairs<T, P> { 142 Pairs { 143 inner: self.inner.iter(), 144 last: self.last.as_ref().map(Box::as_ref).into_iter(), 145 } 146 } 147 148 /// Returns an iterator over the contents of this sequence as mutably 149 /// borrowed punctuated pairs. 150 pub fn pairs_mut(&mut self) -> PairsMut<T, P> { 151 PairsMut { 152 inner: self.inner.iter_mut(), 153 last: self.last.as_mut().map(Box::as_mut).into_iter(), 154 } 155 } 156 157 /// Returns an iterator over the contents of this sequence as owned 158 /// punctuated pairs. 159 pub fn into_pairs(self) -> IntoPairs<T, P> { 160 IntoPairs { 161 inner: self.inner.into_iter(), 162 last: self.last.map(|t| *t).into_iter(), 163 } 164 } 165 166 /// Appends a syntax tree node onto the end of this punctuated sequence. The 167 /// sequence must already have a trailing punctuation, or be empty. 168 /// 169 /// Use [`push`] instead if the punctuated sequence may or may not already 170 /// have trailing punctuation. 171 /// 172 /// [`push`]: Punctuated::push 173 /// 174 /// # Panics 175 /// 176 /// Panics if the sequence is nonempty and does not already have a trailing 177 /// punctuation. 178 pub fn push_value(&mut self, value: T) { 179 assert!( 180 self.empty_or_trailing(), 181 "Punctuated::push_value: cannot push value if Punctuated is missing trailing punctuation", 182 ); 183 184 self.last = Some(Box::new(value)); 185 } 186 187 /// Appends a trailing punctuation onto the end of this punctuated sequence. 188 /// The sequence must be non-empty and must not already have trailing 189 /// punctuation. 190 /// 191 /// # Panics 192 /// 193 /// Panics if the sequence is empty or already has a trailing punctuation. 194 pub fn push_punct(&mut self, punctuation: P) { 195 assert!( 196 self.last.is_some(), 197 "Punctuated::push_punct: cannot push punctuation if Punctuated is empty or already has trailing punctuation", 198 ); 199 200 let last = self.last.take().unwrap(); 201 self.inner.push((*last, punctuation)); 202 } 203 204 /// Removes the last punctuated pair from this sequence, or `None` if the 205 /// sequence is empty. 206 pub fn pop(&mut self) -> Option<Pair<T, P>> { 207 if self.last.is_some() { 208 self.last.take().map(|t| Pair::End(*t)) 209 } else { 210 self.inner.pop().map(|(t, p)| Pair::Punctuated(t, p)) 211 } 212 } 213 214 /// Removes the trailing punctuation from this punctuated sequence, or 215 /// `None` if there isn't any. 216 pub fn pop_punct(&mut self) -> Option<P> { 217 if self.last.is_some() { 218 None 219 } else { 220 let (t, p) = self.inner.pop()?; 221 self.last = Some(Box::new(t)); 222 Some(p) 223 } 224 } 225 226 /// Determines whether this punctuated sequence ends with a trailing 227 /// punctuation. 228 pub fn trailing_punct(&self) -> bool { 229 self.last.is_none() && !self.is_empty() 230 } 231 232 /// Returns true if either this `Punctuated` is empty, or it has a trailing 233 /// punctuation. 234 /// 235 /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`. 236 pub fn empty_or_trailing(&self) -> bool { 237 self.last.is_none() 238 } 239 240 /// Appends a syntax tree node onto the end of this punctuated sequence. 241 /// 242 /// If there is not a trailing punctuation in this sequence when this method 243 /// is called, the default value of punctuation type `P` is inserted before 244 /// the given value of type `T`. 245 pub fn push(&mut self, value: T) 246 where 247 P: Default, 248 { 249 if !self.empty_or_trailing() { 250 self.push_punct(Default::default()); 251 } 252 self.push_value(value); 253 } 254 255 /// Inserts an element at position `index`. 256 /// 257 /// # Panics 258 /// 259 /// Panics if `index` is greater than the number of elements previously in 260 /// this punctuated sequence. 261 pub fn insert(&mut self, index: usize, value: T) 262 where 263 P: Default, 264 { 265 assert!( 266 index <= self.len(), 267 "Punctuated::insert: index out of range", 268 ); 269 270 if index == self.len() { 271 self.push(value); 272 } else { 273 self.inner.insert(index, (value, Default::default())); 274 } 275 } 276 277 /// Clears the sequence of all values and punctuation, making it empty. 278 pub fn clear(&mut self) { 279 self.inner.clear(); 280 self.last = None; 281 } 282 283 /// Parses zero or more occurrences of `T` separated by punctuation of type 284 /// `P`, with optional trailing punctuation. 285 /// 286 /// Parsing continues until the end of this parse stream. The entire content 287 /// of this parse stream must consist of `T` and `P`. 288 #[cfg(feature = "parsing")] 289 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 290 pub fn parse_terminated(input: ParseStream) -> Result<Self> 291 where 292 T: Parse, 293 P: Parse, 294 { 295 Self::parse_terminated_with(input, T::parse) 296 } 297 298 /// Parses zero or more occurrences of `T` using the given parse function, 299 /// separated by punctuation of type `P`, with optional trailing 300 /// punctuation. 301 /// 302 /// Like [`parse_terminated`], the entire content of this stream is expected 303 /// to be parsed. 304 /// 305 /// [`parse_terminated`]: Punctuated::parse_terminated 306 #[cfg(feature = "parsing")] 307 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 308 pub fn parse_terminated_with<'a>( 309 input: ParseStream<'a>, 310 parser: fn(ParseStream<'a>) -> Result<T>, 311 ) -> Result<Self> 312 where 313 P: Parse, 314 { 315 let mut punctuated = Punctuated::new(); 316 317 loop { 318 if input.is_empty() { 319 break; 320 } 321 let value = parser(input)?; 322 punctuated.push_value(value); 323 if input.is_empty() { 324 break; 325 } 326 let punct = input.parse()?; 327 punctuated.push_punct(punct); 328 } 329 330 Ok(punctuated) 331 } 332 333 /// Parses one or more occurrences of `T` separated by punctuation of type 334 /// `P`, not accepting trailing punctuation. 335 /// 336 /// Parsing continues as long as punctuation `P` is present at the head of 337 /// the stream. This method returns upon parsing a `T` and observing that it 338 /// is not followed by a `P`, even if there are remaining tokens in the 339 /// stream. 340 #[cfg(feature = "parsing")] 341 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 342 pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self> 343 where 344 T: Parse, 345 P: Token + Parse, 346 { 347 Self::parse_separated_nonempty_with(input, T::parse) 348 } 349 350 /// Parses one or more occurrences of `T` using the given parse function, 351 /// separated by punctuation of type `P`, not accepting trailing 352 /// punctuation. 353 /// 354 /// Like [`parse_separated_nonempty`], may complete early without parsing 355 /// the entire content of this stream. 356 /// 357 /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty 358 #[cfg(feature = "parsing")] 359 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 360 pub fn parse_separated_nonempty_with<'a>( 361 input: ParseStream<'a>, 362 parser: fn(ParseStream<'a>) -> Result<T>, 363 ) -> Result<Self> 364 where 365 P: Token + Parse, 366 { 367 let mut punctuated = Punctuated::new(); 368 369 loop { 370 let value = parser(input)?; 371 punctuated.push_value(value); 372 if !P::peek(input.cursor()) { 373 break; 374 } 375 let punct = input.parse()?; 376 punctuated.push_punct(punct); 377 } 378 379 Ok(punctuated) 380 } 381 } 382 383 #[cfg(feature = "clone-impls")] 384 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))] 385 impl<T, P> Clone for Punctuated<T, P> 386 where 387 T: Clone, 388 P: Clone, 389 { 390 fn clone(&self) -> Self { 391 Punctuated { 392 inner: self.inner.clone(), 393 last: self.last.clone(), 394 } 395 } 396 397 fn clone_from(&mut self, other: &Self) { 398 self.inner.clone_from(&other.inner); 399 self.last.clone_from(&other.last); 400 } 401 } 402 403 #[cfg(feature = "extra-traits")] 404 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] 405 impl<T, P> Eq for Punctuated<T, P> 406 where 407 T: Eq, 408 P: Eq, 409 { 410 } 411 412 #[cfg(feature = "extra-traits")] 413 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] 414 impl<T, P> PartialEq for Punctuated<T, P> 415 where 416 T: PartialEq, 417 P: PartialEq, 418 { 419 fn eq(&self, other: &Self) -> bool { 420 let Punctuated { inner, last } = self; 421 *inner == other.inner && *last == other.last 422 } 423 } 424 425 #[cfg(feature = "extra-traits")] 426 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] 427 impl<T, P> Hash for Punctuated<T, P> 428 where 429 T: Hash, 430 P: Hash, 431 { 432 fn hash<H: Hasher>(&self, state: &mut H) { 433 let Punctuated { inner, last } = self; 434 inner.hash(state); 435 last.hash(state); 436 } 437 } 438 439 #[cfg(feature = "extra-traits")] 440 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] 441 impl<T: Debug, P: Debug> Debug for Punctuated<T, P> { 442 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 443 let mut list = f.debug_list(); 444 for (t, p) in &self.inner { 445 list.entry(t); 446 list.entry(p); 447 } 448 if let Some(last) = &self.last { 449 list.entry(last); 450 } 451 list.finish() 452 } 453 } 454 455 impl<T, P> FromIterator<T> for Punctuated<T, P> 456 where 457 P: Default, 458 { 459 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self { 460 let mut ret = Punctuated::new(); 461 ret.extend(i); 462 ret 463 } 464 } 465 466 impl<T, P> Extend<T> for Punctuated<T, P> 467 where 468 P: Default, 469 { 470 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) { 471 for value in i { 472 self.push(value); 473 } 474 } 475 } 476 477 impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> { 478 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self { 479 let mut ret = Punctuated::new(); 480 do_extend(&mut ret, i.into_iter()); 481 ret 482 } 483 } 484 485 impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> 486 where 487 P: Default, 488 { 489 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) { 490 if !self.empty_or_trailing() { 491 self.push_punct(P::default()); 492 } 493 do_extend(self, i.into_iter()); 494 } 495 } 496 497 fn do_extend<T, P, I>(punctuated: &mut Punctuated<T, P>, i: I) 498 where 499 I: Iterator<Item = Pair<T, P>>, 500 { 501 let mut nomore = false; 502 for pair in i { 503 if nomore { 504 panic!("punctuated extended with items after a Pair::End"); 505 } 506 match pair { 507 Pair::Punctuated(a, b) => punctuated.inner.push((a, b)), 508 Pair::End(a) => { 509 punctuated.last = Some(Box::new(a)); 510 nomore = true; 511 } 512 } 513 } 514 } 515 516 impl<T, P> IntoIterator for Punctuated<T, P> { 517 type Item = T; 518 type IntoIter = IntoIter<T>; 519 520 fn into_iter(self) -> Self::IntoIter { 521 let mut elements = Vec::with_capacity(self.len()); 522 elements.extend(self.inner.into_iter().map(|pair| pair.0)); 523 elements.extend(self.last.map(|t| *t)); 524 525 IntoIter { 526 inner: elements.into_iter(), 527 } 528 } 529 } 530 531 impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> { 532 type Item = &'a T; 533 type IntoIter = Iter<'a, T>; 534 535 fn into_iter(self) -> Self::IntoIter { 536 Punctuated::iter(self) 537 } 538 } 539 540 impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> { 541 type Item = &'a mut T; 542 type IntoIter = IterMut<'a, T>; 543 544 fn into_iter(self) -> Self::IntoIter { 545 Punctuated::iter_mut(self) 546 } 547 } 548 549 impl<T, P> Default for Punctuated<T, P> { 550 fn default() -> Self { 551 Punctuated::new() 552 } 553 } 554 555 /// An iterator over borrowed pairs of type `Pair<&T, &P>`. 556 /// 557 /// Refer to the [module documentation] for details about punctuated sequences. 558 /// 559 /// [module documentation]: self 560 pub struct Pairs<'a, T: 'a, P: 'a> { 561 inner: slice::Iter<'a, (T, P)>, 562 last: option::IntoIter<&'a T>, 563 } 564 565 impl<'a, T, P> Iterator for Pairs<'a, T, P> { 566 type Item = Pair<&'a T, &'a P>; 567 568 fn next(&mut self) -> Option<Self::Item> { 569 self.inner 570 .next() 571 .map(|(t, p)| Pair::Punctuated(t, p)) 572 .or_else(|| self.last.next().map(Pair::End)) 573 } 574 575 fn size_hint(&self) -> (usize, Option<usize>) { 576 (self.len(), Some(self.len())) 577 } 578 } 579 580 impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> { 581 fn next_back(&mut self) -> Option<Self::Item> { 582 self.last 583 .next() 584 .map(Pair::End) 585 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p))) 586 } 587 } 588 589 impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> { 590 fn len(&self) -> usize { 591 self.inner.len() + self.last.len() 592 } 593 } 594 595 // No Clone bound on T or P. 596 impl<'a, T, P> Clone for Pairs<'a, T, P> { 597 fn clone(&self) -> Self { 598 Pairs { 599 inner: self.inner.clone(), 600 last: self.last.clone(), 601 } 602 } 603 } 604 605 /// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`. 606 /// 607 /// Refer to the [module documentation] for details about punctuated sequences. 608 /// 609 /// [module documentation]: self 610 pub struct PairsMut<'a, T: 'a, P: 'a> { 611 inner: slice::IterMut<'a, (T, P)>, 612 last: option::IntoIter<&'a mut T>, 613 } 614 615 impl<'a, T, P> Iterator for PairsMut<'a, T, P> { 616 type Item = Pair<&'a mut T, &'a mut P>; 617 618 fn next(&mut self) -> Option<Self::Item> { 619 self.inner 620 .next() 621 .map(|(t, p)| Pair::Punctuated(t, p)) 622 .or_else(|| self.last.next().map(Pair::End)) 623 } 624 625 fn size_hint(&self) -> (usize, Option<usize>) { 626 (self.len(), Some(self.len())) 627 } 628 } 629 630 impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> { 631 fn next_back(&mut self) -> Option<Self::Item> { 632 self.last 633 .next() 634 .map(Pair::End) 635 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p))) 636 } 637 } 638 639 impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> { 640 fn len(&self) -> usize { 641 self.inner.len() + self.last.len() 642 } 643 } 644 645 /// An iterator over owned pairs of type `Pair<T, P>`. 646 /// 647 /// Refer to the [module documentation] for details about punctuated sequences. 648 /// 649 /// [module documentation]: self 650 pub struct IntoPairs<T, P> { 651 inner: vec::IntoIter<(T, P)>, 652 last: option::IntoIter<T>, 653 } 654 655 impl<T, P> Iterator for IntoPairs<T, P> { 656 type Item = Pair<T, P>; 657 658 fn next(&mut self) -> Option<Self::Item> { 659 self.inner 660 .next() 661 .map(|(t, p)| Pair::Punctuated(t, p)) 662 .or_else(|| self.last.next().map(Pair::End)) 663 } 664 665 fn size_hint(&self) -> (usize, Option<usize>) { 666 (self.len(), Some(self.len())) 667 } 668 } 669 670 impl<T, P> DoubleEndedIterator for IntoPairs<T, P> { 671 fn next_back(&mut self) -> Option<Self::Item> { 672 self.last 673 .next() 674 .map(Pair::End) 675 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p))) 676 } 677 } 678 679 impl<T, P> ExactSizeIterator for IntoPairs<T, P> { 680 fn len(&self) -> usize { 681 self.inner.len() + self.last.len() 682 } 683 } 684 685 impl<T, P> Clone for IntoPairs<T, P> 686 where 687 T: Clone, 688 P: Clone, 689 { 690 fn clone(&self) -> Self { 691 IntoPairs { 692 inner: self.inner.clone(), 693 last: self.last.clone(), 694 } 695 } 696 } 697 698 /// An iterator over owned values of type `T`. 699 /// 700 /// Refer to the [module documentation] for details about punctuated sequences. 701 /// 702 /// [module documentation]: self 703 pub struct IntoIter<T> { 704 inner: vec::IntoIter<T>, 705 } 706 707 impl<T> Iterator for IntoIter<T> { 708 type Item = T; 709 710 fn next(&mut self) -> Option<Self::Item> { 711 self.inner.next() 712 } 713 714 fn size_hint(&self) -> (usize, Option<usize>) { 715 (self.len(), Some(self.len())) 716 } 717 } 718 719 impl<T> DoubleEndedIterator for IntoIter<T> { 720 fn next_back(&mut self) -> Option<Self::Item> { 721 self.inner.next_back() 722 } 723 } 724 725 impl<T> ExactSizeIterator for IntoIter<T> { 726 fn len(&self) -> usize { 727 self.inner.len() 728 } 729 } 730 731 impl<T> Clone for IntoIter<T> 732 where 733 T: Clone, 734 { 735 fn clone(&self) -> Self { 736 IntoIter { 737 inner: self.inner.clone(), 738 } 739 } 740 } 741 742 /// An iterator over borrowed values of type `&T`. 743 /// 744 /// Refer to the [module documentation] for details about punctuated sequences. 745 /// 746 /// [module documentation]: self 747 pub struct Iter<'a, T: 'a> { 748 inner: Box<NoDrop<dyn IterTrait<'a, T> + 'a>>, 749 } 750 751 trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> + DoubleEndedIterator + ExactSizeIterator { 752 fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>>; 753 } 754 755 struct PrivateIter<'a, T: 'a, P: 'a> { 756 inner: slice::Iter<'a, (T, P)>, 757 last: option::IntoIter<&'a T>, 758 } 759 760 impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P> 761 where 762 slice::Iter<'a, (T, P)>: TrivialDrop, 763 option::IntoIter<&'a T>: TrivialDrop, 764 { 765 } 766 767 #[cfg(any(feature = "full", feature = "derive"))] 768 pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> { 769 Iter { 770 inner: Box::new(NoDrop::new(iter::empty())), 771 } 772 } 773 774 // No Clone bound on T. 775 impl<'a, T> Clone for Iter<'a, T> { 776 fn clone(&self) -> Self { 777 Iter { 778 inner: self.inner.clone_box(), 779 } 780 } 781 } 782 783 impl<'a, T> Iterator for Iter<'a, T> { 784 type Item = &'a T; 785 786 fn next(&mut self) -> Option<Self::Item> { 787 self.inner.next() 788 } 789 790 fn size_hint(&self) -> (usize, Option<usize>) { 791 (self.len(), Some(self.len())) 792 } 793 } 794 795 impl<'a, T> DoubleEndedIterator for Iter<'a, T> { 796 fn next_back(&mut self) -> Option<Self::Item> { 797 self.inner.next_back() 798 } 799 } 800 801 impl<'a, T> ExactSizeIterator for Iter<'a, T> { 802 fn len(&self) -> usize { 803 self.inner.len() 804 } 805 } 806 807 impl<'a, T, P> Iterator for PrivateIter<'a, T, P> { 808 type Item = &'a T; 809 810 fn next(&mut self) -> Option<Self::Item> { 811 self.inner 812 .next() 813 .map(|pair| &pair.0) 814 .or_else(|| self.last.next()) 815 } 816 } 817 818 impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> { 819 fn next_back(&mut self) -> Option<Self::Item> { 820 self.last 821 .next() 822 .or_else(|| self.inner.next_back().map(|pair| &pair.0)) 823 } 824 } 825 826 impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> { 827 fn len(&self) -> usize { 828 self.inner.len() + self.last.len() 829 } 830 } 831 832 // No Clone bound on T or P. 833 impl<'a, T, P> Clone for PrivateIter<'a, T, P> { 834 fn clone(&self) -> Self { 835 PrivateIter { 836 inner: self.inner.clone(), 837 last: self.last.clone(), 838 } 839 } 840 } 841 842 impl<'a, T, I> IterTrait<'a, T> for I 843 where 844 T: 'a, 845 I: DoubleEndedIterator<Item = &'a T> 846 + ExactSizeIterator<Item = &'a T> 847 + Clone 848 + TrivialDrop 849 + 'a, 850 { 851 fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>> { 852 Box::new(NoDrop::new(self.clone())) 853 } 854 } 855 856 /// An iterator over mutably borrowed values of type `&mut T`. 857 /// 858 /// Refer to the [module documentation] for details about punctuated sequences. 859 /// 860 /// [module documentation]: self 861 pub struct IterMut<'a, T: 'a> { 862 inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>, 863 } 864 865 trait IterMutTrait<'a, T: 'a>: 866 DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T> 867 { 868 } 869 870 struct PrivateIterMut<'a, T: 'a, P: 'a> { 871 inner: slice::IterMut<'a, (T, P)>, 872 last: option::IntoIter<&'a mut T>, 873 } 874 875 impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P> 876 where 877 slice::IterMut<'a, (T, P)>: TrivialDrop, 878 option::IntoIter<&'a mut T>: TrivialDrop, 879 { 880 } 881 882 #[cfg(any(feature = "full", feature = "derive"))] 883 pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> { 884 IterMut { 885 inner: Box::new(NoDrop::new(iter::empty())), 886 } 887 } 888 889 impl<'a, T> Iterator for IterMut<'a, T> { 890 type Item = &'a mut T; 891 892 fn next(&mut self) -> Option<Self::Item> { 893 self.inner.next() 894 } 895 896 fn size_hint(&self) -> (usize, Option<usize>) { 897 (self.len(), Some(self.len())) 898 } 899 } 900 901 impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { 902 fn next_back(&mut self) -> Option<Self::Item> { 903 self.inner.next_back() 904 } 905 } 906 907 impl<'a, T> ExactSizeIterator for IterMut<'a, T> { 908 fn len(&self) -> usize { 909 self.inner.len() 910 } 911 } 912 913 impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> { 914 type Item = &'a mut T; 915 916 fn next(&mut self) -> Option<Self::Item> { 917 self.inner 918 .next() 919 .map(|pair| &mut pair.0) 920 .or_else(|| self.last.next()) 921 } 922 } 923 924 impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> { 925 fn next_back(&mut self) -> Option<Self::Item> { 926 self.last 927 .next() 928 .or_else(|| self.inner.next_back().map(|pair| &mut pair.0)) 929 } 930 } 931 932 impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> { 933 fn len(&self) -> usize { 934 self.inner.len() + self.last.len() 935 } 936 } 937 938 impl<'a, T, I> IterMutTrait<'a, T> for I 939 where 940 T: 'a, 941 I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T> + 'a, 942 { 943 } 944 945 /// A single syntax tree node of type `T` followed by its trailing punctuation 946 /// of type `P` if any. 947 /// 948 /// Refer to the [module documentation] for details about punctuated sequences. 949 /// 950 /// [module documentation]: self 951 pub enum Pair<T, P> { 952 Punctuated(T, P), 953 End(T), 954 } 955 956 impl<T, P> Pair<T, P> { 957 /// Extracts the syntax tree node from this punctuated pair, discarding the 958 /// following punctuation. 959 pub fn into_value(self) -> T { 960 match self { 961 Pair::Punctuated(t, _) | Pair::End(t) => t, 962 } 963 } 964 965 /// Borrows the syntax tree node from this punctuated pair. 966 pub fn value(&self) -> &T { 967 match self { 968 Pair::Punctuated(t, _) | Pair::End(t) => t, 969 } 970 } 971 972 /// Mutably borrows the syntax tree node from this punctuated pair. 973 pub fn value_mut(&mut self) -> &mut T { 974 match self { 975 Pair::Punctuated(t, _) | Pair::End(t) => t, 976 } 977 } 978 979 /// Borrows the punctuation from this punctuated pair, unless this pair is 980 /// the final one and there is no trailing punctuation. 981 pub fn punct(&self) -> Option<&P> { 982 match self { 983 Pair::Punctuated(_, p) => Some(p), 984 Pair::End(_) => None, 985 } 986 } 987 988 /// Mutably borrows the punctuation from this punctuated pair, unless the 989 /// pair is the final one and there is no trailing punctuation. 990 /// 991 /// # Example 992 /// 993 /// ``` 994 /// # use proc_macro2::Span; 995 /// # use syn::punctuated::Punctuated; 996 /// # use syn::{parse_quote, Token, TypeParamBound}; 997 /// # 998 /// # let mut punctuated = Punctuated::<TypeParamBound, Token![+]>::new(); 999 /// # let span = Span::call_site(); 1000 /// # 1001 /// punctuated.insert(0, parse_quote!('lifetime)); 1002 /// if let Some(punct) = punctuated.pairs_mut().next().unwrap().punct_mut() { 1003 /// punct.span = span; 1004 /// } 1005 /// ``` 1006 pub fn punct_mut(&mut self) -> Option<&mut P> { 1007 match self { 1008 Pair::Punctuated(_, p) => Some(p), 1009 Pair::End(_) => None, 1010 } 1011 } 1012 1013 /// Creates a punctuated pair out of a syntax tree node and an optional 1014 /// following punctuation. 1015 pub fn new(t: T, p: Option<P>) -> Self { 1016 match p { 1017 Some(p) => Pair::Punctuated(t, p), 1018 None => Pair::End(t), 1019 } 1020 } 1021 1022 /// Produces this punctuated pair as a tuple of syntax tree node and 1023 /// optional following punctuation. 1024 pub fn into_tuple(self) -> (T, Option<P>) { 1025 match self { 1026 Pair::Punctuated(t, p) => (t, Some(p)), 1027 Pair::End(t) => (t, None), 1028 } 1029 } 1030 } 1031 1032 #[cfg(feature = "clone-impls")] 1033 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))] 1034 impl<T, P> Pair<&T, &P> { 1035 pub fn cloned(self) -> Pair<T, P> 1036 where 1037 T: Clone, 1038 P: Clone, 1039 { 1040 match self { 1041 Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()), 1042 Pair::End(t) => Pair::End(t.clone()), 1043 } 1044 } 1045 } 1046 1047 #[cfg(feature = "clone-impls")] 1048 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))] 1049 impl<T, P> Clone for Pair<T, P> 1050 where 1051 T: Clone, 1052 P: Clone, 1053 { 1054 fn clone(&self) -> Self { 1055 match self { 1056 Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()), 1057 Pair::End(t) => Pair::End(t.clone()), 1058 } 1059 } 1060 } 1061 1062 #[cfg(feature = "clone-impls")] 1063 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))] 1064 impl<T, P> Copy for Pair<T, P> 1065 where 1066 T: Copy, 1067 P: Copy, 1068 { 1069 } 1070 1071 impl<T, P> Index<usize> for Punctuated<T, P> { 1072 type Output = T; 1073 1074 fn index(&self, index: usize) -> &Self::Output { 1075 if index == self.len() - 1 { 1076 match &self.last { 1077 Some(t) => t, 1078 None => &self.inner[index].0, 1079 } 1080 } else { 1081 &self.inner[index].0 1082 } 1083 } 1084 } 1085 1086 impl<T, P> IndexMut<usize> for Punctuated<T, P> { 1087 fn index_mut(&mut self, index: usize) -> &mut Self::Output { 1088 if index == self.len() - 1 { 1089 match &mut self.last { 1090 Some(t) => t, 1091 None => &mut self.inner[index].0, 1092 } 1093 } else { 1094 &mut self.inner[index].0 1095 } 1096 } 1097 } 1098 1099 #[cfg(all(feature = "fold", any(feature = "full", feature = "derive")))] 1100 pub(crate) fn fold<T, P, V, F>( 1101 punctuated: Punctuated<T, P>, 1102 fold: &mut V, 1103 mut f: F, 1104 ) -> Punctuated<T, P> 1105 where 1106 V: ?Sized, 1107 F: FnMut(&mut V, T) -> T, 1108 { 1109 Punctuated { 1110 inner: punctuated 1111 .inner 1112 .into_iter() 1113 .map(|(t, p)| (f(fold, t), p)) 1114 .collect(), 1115 last: match punctuated.last { 1116 Some(t) => Some(Box::new(f(fold, *t))), 1117 None => None, 1118 }, 1119 } 1120 } 1121 1122 #[cfg(feature = "printing")] 1123 mod printing { 1124 use crate::punctuated::{Pair, Punctuated}; 1125 use proc_macro2::TokenStream; 1126 use quote::{ToTokens, TokenStreamExt}; 1127 1128 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 1129 impl<T, P> ToTokens for Punctuated<T, P> 1130 where 1131 T: ToTokens, 1132 P: ToTokens, 1133 { 1134 fn to_tokens(&self, tokens: &mut TokenStream) { 1135 tokens.append_all(self.pairs()); 1136 } 1137 } 1138 1139 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 1140 impl<T, P> ToTokens for Pair<T, P> 1141 where 1142 T: ToTokens, 1143 P: ToTokens, 1144 { 1145 fn to_tokens(&self, tokens: &mut TokenStream) { 1146 match self { 1147 Pair::Punctuated(a, b) => { 1148 a.to_tokens(tokens); 1149 b.to_tokens(tokens); 1150 } 1151 Pair::End(a) => a.to_tokens(tokens), 1152 } 1153 } 1154 } 1155 } 1156