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. |
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 | |
59 | impl 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 | |
104 | mod private { |
105 | use proc_macro2::TokenStream; |
106 | |
107 | pub trait Sealed {} |
108 | |
109 | impl Sealed for TokenStream {} |
110 | } |
111 | |