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