File Index
Files and directories
Sign in
FILE

to_tokens.rs

File preview with syntax highlighting.

linux-6.19.14/rust/quote/to_tokens.rs RUST
  1// SPDX-License-Identifier: Apache-2.0 OR MIT
  2
  3use super::TokenStreamExt;
  4use alloc::borrow::Cow;
  5use alloc::rc::Rc;
  6use core::iter;
  7use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
  8use std::ffi::{CStr, CString};
  9
 10/// Types that can be interpolated inside a `quote!` invocation.
 11pub 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
 76impl<T: ?Sized + ToTokens> ToTokens for &T {
 77    fn to_tokens(&self, tokens: &mut TokenStream) {
 78        (**self).to_tokens(tokens);
 79    }
 80}
 81
 82impl<T: ?Sized + ToTokens> ToTokens for &mut T {
 83    fn to_tokens(&self, tokens: &mut TokenStream) {
 84        (**self).to_tokens(tokens);
 85    }
 86}
 87
 88impl<'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
 94impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
 95    fn to_tokens(&self, tokens: &mut TokenStream) {
 96        (**self).to_tokens(tokens);
 97    }
 98}
 99
100impl<T: ?Sized + ToTokens> ToTokens for Rc<T> {
101    fn to_tokens(&self, tokens: &mut TokenStream) {
102        (**self).to_tokens(tokens);
103    }
104}
105
106impl<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
114impl ToTokens for str {
115    fn to_tokens(&self, tokens: &mut TokenStream) {
116        tokens.append(Literal::string(self));
117    }
118}
119
120impl ToTokens for String {
121    fn to_tokens(&self, tokens: &mut TokenStream) {
122        self.as_str().to_tokens(tokens);
123    }
124}
125
126impl ToTokens for i8 {
127    fn to_tokens(&self, tokens: &mut TokenStream) {
128        tokens.append(Literal::i8_suffixed(*self));
129    }
130}
131
132impl ToTokens for i16 {
133    fn to_tokens(&self, tokens: &mut TokenStream) {
134        tokens.append(Literal::i16_suffixed(*self));
135    }
136}
137
138impl ToTokens for i32 {
139    fn to_tokens(&self, tokens: &mut TokenStream) {
140        tokens.append(Literal::i32_suffixed(*self));
141    }
142}
143
144impl ToTokens for i64 {
145    fn to_tokens(&self, tokens: &mut TokenStream) {
146        tokens.append(Literal::i64_suffixed(*self));
147    }
148}
149
150impl ToTokens for i128 {
151    fn to_tokens(&self, tokens: &mut TokenStream) {
152        tokens.append(Literal::i128_suffixed(*self));
153    }
154}
155
156impl ToTokens for isize {
157    fn to_tokens(&self, tokens: &mut TokenStream) {
158        tokens.append(Literal::isize_suffixed(*self));
159    }
160}
161
162impl ToTokens for u8 {
163    fn to_tokens(&self, tokens: &mut TokenStream) {
164        tokens.append(Literal::u8_suffixed(*self));
165    }
166}
167
168impl ToTokens for u16 {
169    fn to_tokens(&self, tokens: &mut TokenStream) {
170        tokens.append(Literal::u16_suffixed(*self));
171    }
172}
173
174impl ToTokens for u32 {
175    fn to_tokens(&self, tokens: &mut TokenStream) {
176        tokens.append(Literal::u32_suffixed(*self));
177    }
178}
179
180impl ToTokens for u64 {
181    fn to_tokens(&self, tokens: &mut TokenStream) {
182        tokens.append(Literal::u64_suffixed(*self));
183    }
184}
185
186impl ToTokens for u128 {
187    fn to_tokens(&self, tokens: &mut TokenStream) {
188        tokens.append(Literal::u128_suffixed(*self));
189    }
190}
191
192impl ToTokens for usize {
193    fn to_tokens(&self, tokens: &mut TokenStream) {
194        tokens.append(Literal::usize_suffixed(*self));
195    }
196}
197
198impl ToTokens for f32 {
199    fn to_tokens(&self, tokens: &mut TokenStream) {
200        tokens.append(Literal::f32_suffixed(*self));
201    }
202}
203
204impl ToTokens for f64 {
205    fn to_tokens(&self, tokens: &mut TokenStream) {
206        tokens.append(Literal::f64_suffixed(*self));
207    }
208}
209
210impl ToTokens for char {
211    fn to_tokens(&self, tokens: &mut TokenStream) {
212        tokens.append(Literal::character(*self));
213    }
214}
215
216impl 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
223impl ToTokens for CStr {
224    fn to_tokens(&self, tokens: &mut TokenStream) {
225        tokens.append(Literal::c_string(self));
226    }
227}
228
229impl ToTokens for CString {
230    fn to_tokens(&self, tokens: &mut TokenStream) {
231        tokens.append(Literal::c_string(self));
232    }
233}
234
235impl ToTokens for Group {
236    fn to_tokens(&self, tokens: &mut TokenStream) {
237        tokens.append(self.clone());
238    }
239}
240
241impl ToTokens for Ident {
242    fn to_tokens(&self, tokens: &mut TokenStream) {
243        tokens.append(self.clone());
244    }
245}
246
247impl ToTokens for Punct {
248    fn to_tokens(&self, tokens: &mut TokenStream) {
249        tokens.append(self.clone());
250    }
251}
252
253impl ToTokens for Literal {
254    fn to_tokens(&self, tokens: &mut TokenStream) {
255        tokens.append(self.clone());
256    }
257}
258
259impl ToTokens for TokenTree {
260    fn to_tokens(&self, tokens: &mut TokenStream) {
261        tokens.append(self.clone());
262    }
263}
264
265impl 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}
~/ Read-only file preview.