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