• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::ToTokens;
2 
3 use std::iter;
4 
5 use 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.
10 pub trait TokenStreamExt: private::Sealed {
11     /// For use by `ToTokens` implementations.
12     ///
13     /// Appends the token specified to this list of tokens.
append<U>(&mut self, token: U) where U: Into<TokenTree>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     /// ```
append_all<I>(&mut self, iter: I) where I: IntoIterator, I::Item: ToTokens35     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`.
append_separated<I, U>(&mut self, iter: I, op: U) where I: IntoIterator, I::Item: ToTokens, U: ToTokens44     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.
append_terminated<I, U>(&mut self, iter: I, term: U) where I: IntoIterator, I::Item: ToTokens, U: ToTokens54     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 
61 impl TokenStreamExt for TokenStream {
append<U>(&mut self, token: U) where U: Into<TokenTree>,62     fn append<U>(&mut self, token: U)
63     where
64         U: Into<TokenTree>,
65     {
66         self.extend(iter::once(token.into()));
67     }
68 
append_all<I>(&mut self, iter: I) where I: IntoIterator, I::Item: ToTokens,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 
append_separated<I, U>(&mut self, iter: I, op: U) where I: IntoIterator, I::Item: ToTokens, U: ToTokens,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 
append_terminated<I, U>(&mut self, iter: I, term: U) where I: IntoIterator, I::Item: ToTokens, U: ToTokens,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 
106 mod private {
107     use proc_macro2::TokenStream;
108 
109     pub trait Sealed {}
110 
111     impl Sealed for TokenStream {}
112 }
113