]>
Commit | Line | Data |
---|---|---|
e74abb32 | 1 | use super::ToTokens; |
f2b60f7d | 2 | use core::iter; |
e74abb32 XL |
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 | } |