quote/
ext.rs

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