File Index
Files and directories
Sign in
FILE

punctuated.rs

File preview with syntax highlighting.

linux-6.19.14/rust/syn/punctuated.rs RUST
   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
  25use crate::drops::{NoDrop, TrivialDrop};
  26#[cfg(feature = "parsing")]
  27use crate::error::Result;
  28#[cfg(feature = "parsing")]
  29use crate::parse::{Parse, ParseStream};
  30#[cfg(feature = "parsing")]
  31use crate::token::Token;
  32#[cfg(feature = "extra-traits")]
  33use std::fmt::{self, Debug};
  34#[cfg(feature = "extra-traits")]
  35use std::hash::{Hash, Hasher};
  36#[cfg(any(feature = "full", feature = "derive"))]
  37use std::iter;
  38use std::ops::{Index, IndexMut};
  39use std::option;
  40use std::slice;
  41use 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
  49pub struct Punctuated<T, P> {
  50    inner: Vec<(T, P)>,
  51    last: Option<Box<T>>,
  52}
  53
  54impl<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")))]
 387impl<T, P> Clone for Punctuated<T, P>
 388where
 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")))]
 407impl<T, P> Eq for Punctuated<T, P>
 408where
 409    T: Eq,
 410    P: Eq,
 411{
 412}
 413
 414#[cfg(feature = "extra-traits")]
 415#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
 416impl<T, P> PartialEq for Punctuated<T, P>
 417where
 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")))]
 429impl<T, P> Hash for Punctuated<T, P>
 430where
 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")))]
 443impl<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
 457impl<T, P> FromIterator<T> for Punctuated<T, P>
 458where
 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
 468impl<T, P> Extend<T> for Punctuated<T, P>
 469where
 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
 479impl<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
 487impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P>
 488where
 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
 499fn do_extend<T, P, I>(punctuated: &mut Punctuated<T, P>, i: I)
 500where
 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
 518impl<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
 533impl<'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
 542impl<'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
 551impl<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
 562pub struct Pairs<'a, T: 'a, P: 'a> {
 563    inner: slice::Iter<'a, (T, P)>,
 564    last: option::IntoIter<&'a T>,
 565}
 566
 567impl<'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
 582impl<'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
 591impl<'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.
 598impl<'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
 612pub struct PairsMut<'a, T: 'a, P: 'a> {
 613    inner: slice::IterMut<'a, (T, P)>,
 614    last: option::IntoIter<&'a mut T>,
 615}
 616
 617impl<'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
 632impl<'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
 641impl<'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
 652pub struct IntoPairs<T, P> {
 653    inner: vec::IntoIter<(T, P)>,
 654    last: option::IntoIter<T>,
 655}
 656
 657impl<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
 672impl<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
 681impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
 682    fn len(&self) -> usize {
 683        self.inner.len() + self.last.len()
 684    }
 685}
 686
 687impl<T, P> Clone for IntoPairs<T, P>
 688where
 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
 705pub struct IntoIter<T> {
 706    inner: vec::IntoIter<T>,
 707}
 708
 709impl<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
 721impl<T> DoubleEndedIterator for IntoIter<T> {
 722    fn next_back(&mut self) -> Option<Self::Item> {
 723        self.inner.next_back()
 724    }
 725}
 726
 727impl<T> ExactSizeIterator for IntoIter<T> {
 728    fn len(&self) -> usize {
 729        self.inner.len()
 730    }
 731}
 732
 733impl<T> Clone for IntoIter<T>
 734where
 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
 749pub struct Iter<'a, T: 'a> {
 750    inner: Box<NoDrop<dyn IterTrait<'a, T> + 'a>>,
 751}
 752
 753trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> + DoubleEndedIterator + ExactSizeIterator {
 754    fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>>;
 755}
 756
 757struct PrivateIter<'a, T: 'a, P: 'a> {
 758    inner: slice::Iter<'a, (T, P)>,
 759    last: option::IntoIter<&'a T>,
 760}
 761
 762impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P>
 763where
 764    slice::Iter<'a, (T, P)>: TrivialDrop,
 765    option::IntoIter<&'a T>: TrivialDrop,
 766{
 767}
 768
 769#[cfg(any(feature = "full", feature = "derive"))]
 770pub(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.
 777impl<'a, T> Clone for Iter<'a, T> {
 778    fn clone(&self) -> Self {
 779        Iter {
 780            inner: self.inner.clone_box(),
 781        }
 782    }
 783}
 784
 785impl<'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
 797impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
 798    fn next_back(&mut self) -> Option<Self::Item> {
 799        self.inner.next_back()
 800    }
 801}
 802
 803impl<'a, T> ExactSizeIterator for Iter<'a, T> {
 804    fn len(&self) -> usize {
 805        self.inner.len()
 806    }
 807}
 808
 809impl<'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
 820impl<'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
 828impl<'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.
 835impl<'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
 844impl<'a, T, I> IterTrait<'a, T> for I
 845where
 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
 863pub struct IterMut<'a, T: 'a> {
 864    inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>,
 865}
 866
 867trait IterMutTrait<'a, T: 'a>:
 868    DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
 869{
 870}
 871
 872struct PrivateIterMut<'a, T: 'a, P: 'a> {
 873    inner: slice::IterMut<'a, (T, P)>,
 874    last: option::IntoIter<&'a mut T>,
 875}
 876
 877impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P>
 878where
 879    slice::IterMut<'a, (T, P)>: TrivialDrop,
 880    option::IntoIter<&'a mut T>: TrivialDrop,
 881{
 882}
 883
 884#[cfg(any(feature = "full", feature = "derive"))]
 885pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
 886    IterMut {
 887        inner: Box::new(NoDrop::new(iter::empty())),
 888    }
 889}
 890
 891impl<'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
 903impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
 904    fn next_back(&mut self) -> Option<Self::Item> {
 905        self.inner.next_back()
 906    }
 907}
 908
 909impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
 910    fn len(&self) -> usize {
 911        self.inner.len()
 912    }
 913}
 914
 915impl<'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
 926impl<'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
 934impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
 935    fn len(&self) -> usize {
 936        self.inner.len() + self.last.len()
 937    }
 938}
 939
 940impl<'a, T, I> IterMutTrait<'a, T> for I
 941where
 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
 953pub enum Pair<T, P> {
 954    Punctuated(T, P),
 955    End(T),
 956}
 957
 958impl<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")))]
1036impl<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")))]
1051impl<T, P> Clone for Pair<T, P>
1052where
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")))]
1066impl<T, P> Copy for Pair<T, P>
1067where
1068    T: Copy,
1069    P: Copy,
1070{
1071}
1072
1073impl<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
1088impl<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")))]
1102pub(crate) fn fold<T, P, V, F>(
1103    punctuated: Punctuated<T, P>,
1104    fold: &mut V,
1105    mut f: F,
1106) -> Punctuated<T, P>
1107where
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")]
1125mod 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}
~/ Read-only file preview.