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}