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