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