windows_tokens/
to_tokens.rs

1use std::borrow::Cow;
2use std::rc::Rc;
3
4use crate::{Literal, TokenStream};
5
6/// Types that can be interpolated inside a `quote!` invocation.
7///
8/// [`quote!`]: macro.quote.html
9pub trait ToTokens {
10    /// Write `self` to the given `TokenStream`.
11    fn to_tokens(&self, tokens: &mut TokenStream);
12
13    /// Convert `self` directly into a `TokenStream` object.
14    ///
15    /// This method is implicitly implemented using `to_tokens`, and acts as a
16    /// convenience method for consumers of the `ToTokens` trait.
17    fn to_token_stream(&self) -> TokenStream {
18        let mut tokens = TokenStream::new();
19        self.to_tokens(&mut tokens);
20        tokens
21    }
22
23    /// Convert `self` directly into a `TokenStream` object.
24    ///
25    /// This method is implicitly implemented using `to_tokens`, and acts as a
26    /// convenience method for consumers of the `ToTokens` trait.
27    fn into_token_stream(self) -> TokenStream
28    where
29        Self: Sized,
30    {
31        self.to_token_stream()
32    }
33}
34
35impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T {
36    fn to_tokens(&self, tokens: &mut TokenStream) {
37        (**self).to_tokens(tokens);
38    }
39}
40
41impl<'a, T: ?Sized + ToTokens> ToTokens for &'a mut T {
42    fn to_tokens(&self, tokens: &mut TokenStream) {
43        (**self).to_tokens(tokens);
44    }
45}
46
47impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> {
48    fn to_tokens(&self, tokens: &mut TokenStream) {
49        (**self).to_tokens(tokens);
50    }
51}
52
53impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
54    fn to_tokens(&self, tokens: &mut TokenStream) {
55        (**self).to_tokens(tokens);
56    }
57}
58
59impl<T: ?Sized + ToTokens> ToTokens for Rc<T> {
60    fn to_tokens(&self, tokens: &mut TokenStream) {
61        (**self).to_tokens(tokens);
62    }
63}
64
65impl<T: ToTokens> ToTokens for Option<T> {
66    fn to_tokens(&self, tokens: &mut TokenStream) {
67        if let Some(ref t) = *self {
68            t.to_tokens(tokens);
69        }
70    }
71}
72
73impl ToTokens for str {
74    fn to_tokens(&self, tokens: &mut TokenStream) {
75        tokens.push('"');
76        tokens.push_str(self);
77        tokens.push('"');
78    }
79}
80
81impl ToTokens for String {
82    fn to_tokens(&self, tokens: &mut TokenStream) {
83        self.as_str().to_tokens(tokens);
84    }
85}
86
87macro_rules! primitive {
88    ($($t:ident => $name:ident)*) => ($(
89        impl ToTokens for $t {
90            fn to_tokens(&self, tokens: &mut TokenStream) {
91                tokens.push_space();
92                tokens.push_str(&self.to_string());
93                tokens.push_str(stringify!($t));
94            }
95        }
96    )*)
97}
98
99primitive! {
100    i8 => i8_suffixed
101    i16 => i16_suffixed
102    i32 => i32_suffixed
103    i64 => i64_suffixed
104    i128 => i128_suffixed
105    isize => isize_suffixed
106
107    u8 => u8_suffixed
108    u16 => u16_suffixed
109    u32 => u32_suffixed
110    u64 => u64_suffixed
111    u128 => u128_suffixed
112    usize => usize_suffixed
113
114    f32 => f32_suffixed
115    f64 => f64_suffixed
116}
117
118impl ToTokens for char {
119    fn to_tokens(&self, tokens: &mut TokenStream) {
120        tokens.push_space();
121        tokens.push('\'');
122        tokens.push(*self);
123        tokens.push('\'');
124    }
125}
126
127impl ToTokens for bool {
128    fn to_tokens(&self, tokens: &mut TokenStream) {
129        let word = if *self { "true" } else { "false" };
130        tokens.push_space();
131        tokens.push_str(word);
132    }
133}
134
135impl ToTokens for Literal {
136    fn to_tokens(&self, tokens: &mut TokenStream) {
137        tokens.push_str(self.as_str());
138    }
139}
140
141impl ToTokens for TokenStream {
142    fn to_tokens(&self, dst: &mut TokenStream) {
143        dst.combine(self);
144    }
145
146    fn into_token_stream(self) -> TokenStream {
147        self
148    }
149}