quote/
ext.rs

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