1e31f0860Sopenharmony_ciuse super::ToTokens;
2e31f0860Sopenharmony_ciuse core::iter;
3e31f0860Sopenharmony_ciuse proc_macro2::{TokenStream, TokenTree};
4e31f0860Sopenharmony_ci
5e31f0860Sopenharmony_ci/// TokenStream extension trait with methods for appending tokens.
6e31f0860Sopenharmony_ci///
7e31f0860Sopenharmony_ci/// This trait is sealed and cannot be implemented outside of the `quote` crate.
8e31f0860Sopenharmony_cipub trait TokenStreamExt: private::Sealed {
9e31f0860Sopenharmony_ci    /// For use by `ToTokens` implementations.
10e31f0860Sopenharmony_ci    ///
11e31f0860Sopenharmony_ci    /// Appends the token specified to this list of tokens.
12e31f0860Sopenharmony_ci    fn append<U>(&mut self, token: U)
13e31f0860Sopenharmony_ci    where
14e31f0860Sopenharmony_ci        U: Into<TokenTree>;
15e31f0860Sopenharmony_ci
16e31f0860Sopenharmony_ci    /// For use by `ToTokens` implementations.
17e31f0860Sopenharmony_ci    ///
18e31f0860Sopenharmony_ci    /// ```
19e31f0860Sopenharmony_ci    /// # use quote::{quote, TokenStreamExt, ToTokens};
20e31f0860Sopenharmony_ci    /// # use proc_macro2::TokenStream;
21e31f0860Sopenharmony_ci    /// #
22e31f0860Sopenharmony_ci    /// struct X;
23e31f0860Sopenharmony_ci    ///
24e31f0860Sopenharmony_ci    /// impl ToTokens for X {
25e31f0860Sopenharmony_ci    ///     fn to_tokens(&self, tokens: &mut TokenStream) {
26e31f0860Sopenharmony_ci    ///         tokens.append_all(&[true, false]);
27e31f0860Sopenharmony_ci    ///     }
28e31f0860Sopenharmony_ci    /// }
29e31f0860Sopenharmony_ci    ///
30e31f0860Sopenharmony_ci    /// let tokens = quote!(#X);
31e31f0860Sopenharmony_ci    /// assert_eq!(tokens.to_string(), "true false");
32e31f0860Sopenharmony_ci    /// ```
33e31f0860Sopenharmony_ci    fn append_all<I>(&mut self, iter: I)
34e31f0860Sopenharmony_ci    where
35e31f0860Sopenharmony_ci        I: IntoIterator,
36e31f0860Sopenharmony_ci        I::Item: ToTokens;
37e31f0860Sopenharmony_ci
38e31f0860Sopenharmony_ci    /// For use by `ToTokens` implementations.
39e31f0860Sopenharmony_ci    ///
40e31f0860Sopenharmony_ci    /// Appends all of the items in the iterator `I`, separated by the tokens
41e31f0860Sopenharmony_ci    /// `U`.
42e31f0860Sopenharmony_ci    fn append_separated<I, U>(&mut self, iter: I, op: U)
43e31f0860Sopenharmony_ci    where
44e31f0860Sopenharmony_ci        I: IntoIterator,
45e31f0860Sopenharmony_ci        I::Item: ToTokens,
46e31f0860Sopenharmony_ci        U: ToTokens;
47e31f0860Sopenharmony_ci
48e31f0860Sopenharmony_ci    /// For use by `ToTokens` implementations.
49e31f0860Sopenharmony_ci    ///
50e31f0860Sopenharmony_ci    /// Appends all tokens in the iterator `I`, appending `U` after each
51e31f0860Sopenharmony_ci    /// element, including after the last element of the iterator.
52e31f0860Sopenharmony_ci    fn append_terminated<I, U>(&mut self, iter: I, term: U)
53e31f0860Sopenharmony_ci    where
54e31f0860Sopenharmony_ci        I: IntoIterator,
55e31f0860Sopenharmony_ci        I::Item: ToTokens,
56e31f0860Sopenharmony_ci        U: ToTokens;
57e31f0860Sopenharmony_ci}
58e31f0860Sopenharmony_ci
59e31f0860Sopenharmony_ciimpl TokenStreamExt for TokenStream {
60e31f0860Sopenharmony_ci    fn append<U>(&mut self, token: U)
61e31f0860Sopenharmony_ci    where
62e31f0860Sopenharmony_ci        U: Into<TokenTree>,
63e31f0860Sopenharmony_ci    {
64e31f0860Sopenharmony_ci        self.extend(iter::once(token.into()));
65e31f0860Sopenharmony_ci    }
66e31f0860Sopenharmony_ci
67e31f0860Sopenharmony_ci    fn append_all<I>(&mut self, iter: I)
68e31f0860Sopenharmony_ci    where
69e31f0860Sopenharmony_ci        I: IntoIterator,
70e31f0860Sopenharmony_ci        I::Item: ToTokens,
71e31f0860Sopenharmony_ci    {
72e31f0860Sopenharmony_ci        for token in iter {
73e31f0860Sopenharmony_ci            token.to_tokens(self);
74e31f0860Sopenharmony_ci        }
75e31f0860Sopenharmony_ci    }
76e31f0860Sopenharmony_ci
77e31f0860Sopenharmony_ci    fn append_separated<I, U>(&mut self, iter: I, op: U)
78e31f0860Sopenharmony_ci    where
79e31f0860Sopenharmony_ci        I: IntoIterator,
80e31f0860Sopenharmony_ci        I::Item: ToTokens,
81e31f0860Sopenharmony_ci        U: ToTokens,
82e31f0860Sopenharmony_ci    {
83e31f0860Sopenharmony_ci        for (i, token) in iter.into_iter().enumerate() {
84e31f0860Sopenharmony_ci            if i > 0 {
85e31f0860Sopenharmony_ci                op.to_tokens(self);
86e31f0860Sopenharmony_ci            }
87e31f0860Sopenharmony_ci            token.to_tokens(self);
88e31f0860Sopenharmony_ci        }
89e31f0860Sopenharmony_ci    }
90e31f0860Sopenharmony_ci
91e31f0860Sopenharmony_ci    fn append_terminated<I, U>(&mut self, iter: I, term: U)
92e31f0860Sopenharmony_ci    where
93e31f0860Sopenharmony_ci        I: IntoIterator,
94e31f0860Sopenharmony_ci        I::Item: ToTokens,
95e31f0860Sopenharmony_ci        U: ToTokens,
96e31f0860Sopenharmony_ci    {
97e31f0860Sopenharmony_ci        for token in iter {
98e31f0860Sopenharmony_ci            token.to_tokens(self);
99e31f0860Sopenharmony_ci            term.to_tokens(self);
100e31f0860Sopenharmony_ci        }
101e31f0860Sopenharmony_ci    }
102e31f0860Sopenharmony_ci}
103e31f0860Sopenharmony_ci
104e31f0860Sopenharmony_cimod private {
105e31f0860Sopenharmony_ci    use proc_macro2::TokenStream;
106e31f0860Sopenharmony_ci
107e31f0860Sopenharmony_ci    pub trait Sealed {}
108e31f0860Sopenharmony_ci
109e31f0860Sopenharmony_ci    impl Sealed for TokenStream {}
110e31f0860Sopenharmony_ci}
111