Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/rust/quote/to_tokens.rs
38271 views
1
// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3
use super::TokenStreamExt;
4
use alloc::borrow::Cow;
5
use alloc::rc::Rc;
6
use core::iter;
7
use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
8
use std::ffi::{CStr, CString};
9
10
/// Types that can be interpolated inside a `quote!` invocation.
11
pub trait ToTokens {
12
/// Write `self` to the given `TokenStream`.
13
///
14
/// The token append methods provided by the [`TokenStreamExt`] extension
15
/// trait may be useful for implementing `ToTokens`.
16
///
17
/// # Example
18
///
19
/// Example implementation for a struct representing Rust paths like
20
/// `std::cmp::PartialEq`:
21
///
22
/// ```
23
/// use proc_macro2::{TokenTree, Spacing, Span, Punct, TokenStream};
24
/// use quote::{TokenStreamExt, ToTokens};
25
///
26
/// pub struct Path {
27
/// pub global: bool,
28
/// pub segments: Vec<PathSegment>,
29
/// }
30
///
31
/// impl ToTokens for Path {
32
/// fn to_tokens(&self, tokens: &mut TokenStream) {
33
/// for (i, segment) in self.segments.iter().enumerate() {
34
/// if i > 0 || self.global {
35
/// // Double colon `::`
36
/// tokens.append(Punct::new(':', Spacing::Joint));
37
/// tokens.append(Punct::new(':', Spacing::Alone));
38
/// }
39
/// segment.to_tokens(tokens);
40
/// }
41
/// }
42
/// }
43
/// #
44
/// # pub struct PathSegment;
45
/// #
46
/// # impl ToTokens for PathSegment {
47
/// # fn to_tokens(&self, tokens: &mut TokenStream) {
48
/// # unimplemented!()
49
/// # }
50
/// # }
51
/// ```
52
fn to_tokens(&self, tokens: &mut TokenStream);
53
54
/// Convert `self` directly into a `TokenStream` object.
55
///
56
/// This method is implicitly implemented using `to_tokens`, and acts as a
57
/// convenience method for consumers of the `ToTokens` trait.
58
fn to_token_stream(&self) -> TokenStream {
59
let mut tokens = TokenStream::new();
60
self.to_tokens(&mut tokens);
61
tokens
62
}
63
64
/// Convert `self` directly into a `TokenStream` object.
65
///
66
/// This method is implicitly implemented using `to_tokens`, and acts as a
67
/// convenience method for consumers of the `ToTokens` trait.
68
fn into_token_stream(self) -> TokenStream
69
where
70
Self: Sized,
71
{
72
self.to_token_stream()
73
}
74
}
75
76
impl<T: ?Sized + ToTokens> ToTokens for &T {
77
fn to_tokens(&self, tokens: &mut TokenStream) {
78
(**self).to_tokens(tokens);
79
}
80
}
81
82
impl<T: ?Sized + ToTokens> ToTokens for &mut T {
83
fn to_tokens(&self, tokens: &mut TokenStream) {
84
(**self).to_tokens(tokens);
85
}
86
}
87
88
impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> {
89
fn to_tokens(&self, tokens: &mut TokenStream) {
90
(**self).to_tokens(tokens);
91
}
92
}
93
94
impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
95
fn to_tokens(&self, tokens: &mut TokenStream) {
96
(**self).to_tokens(tokens);
97
}
98
}
99
100
impl<T: ?Sized + ToTokens> ToTokens for Rc<T> {
101
fn to_tokens(&self, tokens: &mut TokenStream) {
102
(**self).to_tokens(tokens);
103
}
104
}
105
106
impl<T: ToTokens> ToTokens for Option<T> {
107
fn to_tokens(&self, tokens: &mut TokenStream) {
108
if let Some(t) = self {
109
t.to_tokens(tokens);
110
}
111
}
112
}
113
114
impl ToTokens for str {
115
fn to_tokens(&self, tokens: &mut TokenStream) {
116
tokens.append(Literal::string(self));
117
}
118
}
119
120
impl ToTokens for String {
121
fn to_tokens(&self, tokens: &mut TokenStream) {
122
self.as_str().to_tokens(tokens);
123
}
124
}
125
126
impl ToTokens for i8 {
127
fn to_tokens(&self, tokens: &mut TokenStream) {
128
tokens.append(Literal::i8_suffixed(*self));
129
}
130
}
131
132
impl ToTokens for i16 {
133
fn to_tokens(&self, tokens: &mut TokenStream) {
134
tokens.append(Literal::i16_suffixed(*self));
135
}
136
}
137
138
impl ToTokens for i32 {
139
fn to_tokens(&self, tokens: &mut TokenStream) {
140
tokens.append(Literal::i32_suffixed(*self));
141
}
142
}
143
144
impl ToTokens for i64 {
145
fn to_tokens(&self, tokens: &mut TokenStream) {
146
tokens.append(Literal::i64_suffixed(*self));
147
}
148
}
149
150
impl ToTokens for i128 {
151
fn to_tokens(&self, tokens: &mut TokenStream) {
152
tokens.append(Literal::i128_suffixed(*self));
153
}
154
}
155
156
impl ToTokens for isize {
157
fn to_tokens(&self, tokens: &mut TokenStream) {
158
tokens.append(Literal::isize_suffixed(*self));
159
}
160
}
161
162
impl ToTokens for u8 {
163
fn to_tokens(&self, tokens: &mut TokenStream) {
164
tokens.append(Literal::u8_suffixed(*self));
165
}
166
}
167
168
impl ToTokens for u16 {
169
fn to_tokens(&self, tokens: &mut TokenStream) {
170
tokens.append(Literal::u16_suffixed(*self));
171
}
172
}
173
174
impl ToTokens for u32 {
175
fn to_tokens(&self, tokens: &mut TokenStream) {
176
tokens.append(Literal::u32_suffixed(*self));
177
}
178
}
179
180
impl ToTokens for u64 {
181
fn to_tokens(&self, tokens: &mut TokenStream) {
182
tokens.append(Literal::u64_suffixed(*self));
183
}
184
}
185
186
impl ToTokens for u128 {
187
fn to_tokens(&self, tokens: &mut TokenStream) {
188
tokens.append(Literal::u128_suffixed(*self));
189
}
190
}
191
192
impl ToTokens for usize {
193
fn to_tokens(&self, tokens: &mut TokenStream) {
194
tokens.append(Literal::usize_suffixed(*self));
195
}
196
}
197
198
impl ToTokens for f32 {
199
fn to_tokens(&self, tokens: &mut TokenStream) {
200
tokens.append(Literal::f32_suffixed(*self));
201
}
202
}
203
204
impl ToTokens for f64 {
205
fn to_tokens(&self, tokens: &mut TokenStream) {
206
tokens.append(Literal::f64_suffixed(*self));
207
}
208
}
209
210
impl ToTokens for char {
211
fn to_tokens(&self, tokens: &mut TokenStream) {
212
tokens.append(Literal::character(*self));
213
}
214
}
215
216
impl ToTokens for bool {
217
fn to_tokens(&self, tokens: &mut TokenStream) {
218
let word = if *self { "true" } else { "false" };
219
tokens.append(Ident::new(word, Span::call_site()));
220
}
221
}
222
223
impl ToTokens for CStr {
224
fn to_tokens(&self, tokens: &mut TokenStream) {
225
tokens.append(Literal::c_string(self));
226
}
227
}
228
229
impl ToTokens for CString {
230
fn to_tokens(&self, tokens: &mut TokenStream) {
231
tokens.append(Literal::c_string(self));
232
}
233
}
234
235
impl ToTokens for Group {
236
fn to_tokens(&self, tokens: &mut TokenStream) {
237
tokens.append(self.clone());
238
}
239
}
240
241
impl ToTokens for Ident {
242
fn to_tokens(&self, tokens: &mut TokenStream) {
243
tokens.append(self.clone());
244
}
245
}
246
247
impl ToTokens for Punct {
248
fn to_tokens(&self, tokens: &mut TokenStream) {
249
tokens.append(self.clone());
250
}
251
}
252
253
impl ToTokens for Literal {
254
fn to_tokens(&self, tokens: &mut TokenStream) {
255
tokens.append(self.clone());
256
}
257
}
258
259
impl ToTokens for TokenTree {
260
fn to_tokens(&self, tokens: &mut TokenStream) {
261
tokens.append(self.clone());
262
}
263
}
264
265
impl ToTokens for TokenStream {
266
fn to_tokens(&self, tokens: &mut TokenStream) {
267
tokens.extend(iter::once(self.clone()));
268
}
269
270
fn into_token_stream(self) -> TokenStream {
271
self
272
}
273
}
274
275