pin_init_internal/macros/
quote.rs1use proc_macro::{TokenStream, TokenTree};
4
5pub(crate) trait ToTokens {
6 fn to_tokens(&self, tokens: &mut TokenStream);
7}
8
9impl<T: ToTokens> ToTokens for Option<T> {
10 fn to_tokens(&self, tokens: &mut TokenStream) {
11 if let Some(v) = self {
12 v.to_tokens(tokens);
13 }
14 }
15}
16
17impl ToTokens for proc_macro::Group {
18 fn to_tokens(&self, tokens: &mut TokenStream) {
19 tokens.extend([TokenTree::from(self.clone())]);
20 }
21}
22
23impl ToTokens for proc_macro::Ident {
24 fn to_tokens(&self, tokens: &mut TokenStream) {
25 tokens.extend([TokenTree::from(self.clone())]);
26 }
27}
28
29impl ToTokens for TokenTree {
30 fn to_tokens(&self, tokens: &mut TokenStream) {
31 tokens.extend([self.clone()]);
32 }
33}
34
35impl ToTokens for TokenStream {
36 fn to_tokens(&self, tokens: &mut TokenStream) {
37 tokens.extend(self.clone());
38 }
39}
40
41macro_rules! quote_spanned {
48 ($span:expr => $($tt:tt)*) => {{
49 let mut tokens = ::proc_macro::TokenStream::new();
50 {
51 let span = $span;
52 quote_spanned!(@proc tokens span $($tt)*);
53 }
54 tokens
55 }};
56 (@proc $v:ident $span:ident) => {};
57 (@proc $v:ident $span:ident #$id:ident $($tt:tt)*) => {
58 $crate::quote::ToTokens::to_tokens(&$id, &mut $v);
59 quote_spanned!(@proc $v $span $($tt)*);
60 };
61 (@proc $v:ident $span:ident #(#$id:ident)* $($tt:tt)*) => {
62 for token in $id {
63 $crate::quote::ToTokens::to_tokens(&token, &mut $v);
64 }
65 quote_spanned!(@proc $v $span $($tt)*);
66 };
67 (@proc $v:ident $span:ident ( $($inner:tt)* ) $($tt:tt)*) => {
68 #[allow(unused_mut)]
69 let mut tokens = ::proc_macro::TokenStream::new();
70 quote_spanned!(@proc tokens $span $($inner)*);
71 $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
72 ::proc_macro::Delimiter::Parenthesis,
73 tokens,
74 ))]);
75 quote_spanned!(@proc $v $span $($tt)*);
76 };
77 (@proc $v:ident $span:ident [ $($inner:tt)* ] $($tt:tt)*) => {
78 let mut tokens = ::proc_macro::TokenStream::new();
79 quote_spanned!(@proc tokens $span $($inner)*);
80 $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
81 ::proc_macro::Delimiter::Bracket,
82 tokens,
83 ))]);
84 quote_spanned!(@proc $v $span $($tt)*);
85 };
86 (@proc $v:ident $span:ident { $($inner:tt)* } $($tt:tt)*) => {
87 let mut tokens = ::proc_macro::TokenStream::new();
88 quote_spanned!(@proc tokens $span $($inner)*);
89 $v.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
90 ::proc_macro::Delimiter::Brace,
91 tokens,
92 ))]);
93 quote_spanned!(@proc $v $span $($tt)*);
94 };
95 (@proc $v:ident $span:ident :: $($tt:tt)*) => {
96 $v.extend([::proc_macro::Spacing::Joint, ::proc_macro::Spacing::Alone].map(|spacing| {
97 ::proc_macro::TokenTree::Punct(::proc_macro::Punct::new(':', spacing))
98 }));
99 quote_spanned!(@proc $v $span $($tt)*);
100 };
101 (@proc $v:ident $span:ident : $($tt:tt)*) => {
102 $v.extend([::proc_macro::TokenTree::Punct(
103 ::proc_macro::Punct::new(':', ::proc_macro::Spacing::Alone),
104 )]);
105 quote_spanned!(@proc $v $span $($tt)*);
106 };
107 (@proc $v:ident $span:ident , $($tt:tt)*) => {
108 $v.extend([::proc_macro::TokenTree::Punct(
109 ::proc_macro::Punct::new(',', ::proc_macro::Spacing::Alone),
110 )]);
111 quote_spanned!(@proc $v $span $($tt)*);
112 };
113 (@proc $v:ident $span:ident @ $($tt:tt)*) => {
114 $v.extend([::proc_macro::TokenTree::Punct(
115 ::proc_macro::Punct::new('@', ::proc_macro::Spacing::Alone),
116 )]);
117 quote_spanned!(@proc $v $span $($tt)*);
118 };
119 (@proc $v:ident $span:ident ! $($tt:tt)*) => {
120 $v.extend([::proc_macro::TokenTree::Punct(
121 ::proc_macro::Punct::new('!', ::proc_macro::Spacing::Alone),
122 )]);
123 quote_spanned!(@proc $v $span $($tt)*);
124 };
125 (@proc $v:ident $span:ident ; $($tt:tt)*) => {
126 $v.extend([::proc_macro::TokenTree::Punct(
127 ::proc_macro::Punct::new(';', ::proc_macro::Spacing::Alone),
128 )]);
129 quote_spanned!(@proc $v $span $($tt)*);
130 };
131 (@proc $v:ident $span:ident + $($tt:tt)*) => {
132 $v.extend([::proc_macro::TokenTree::Punct(
133 ::proc_macro::Punct::new('+', ::proc_macro::Spacing::Alone),
134 )]);
135 quote_spanned!(@proc $v $span $($tt)*);
136 };
137 (@proc $v:ident $span:ident = $($tt:tt)*) => {
138 $v.extend([::proc_macro::TokenTree::Punct(
139 ::proc_macro::Punct::new('=', ::proc_macro::Spacing::Alone),
140 )]);
141 quote_spanned!(@proc $v $span $($tt)*);
142 };
143 (@proc $v:ident $span:ident # $($tt:tt)*) => {
144 $v.extend([::proc_macro::TokenTree::Punct(
145 ::proc_macro::Punct::new('#', ::proc_macro::Spacing::Alone),
146 )]);
147 quote_spanned!(@proc $v $span $($tt)*);
148 };
149 (@proc $v:ident $span:ident _ $($tt:tt)*) => {
150 $v.extend([::proc_macro::TokenTree::Ident(
151 ::proc_macro::Ident::new("_", $span),
152 )]);
153 quote_spanned!(@proc $v $span $($tt)*);
154 };
155 (@proc $v:ident $span:ident $id:ident $($tt:tt)*) => {
156 $v.extend([::proc_macro::TokenTree::Ident(
157 ::proc_macro::Ident::new(stringify!($id), $span),
158 )]);
159 quote_spanned!(@proc $v $span $($tt)*);
160 };
161}
162
163macro_rules! quote {
172 ($($tt:tt)*) => {
173 quote_spanned!(::proc_macro::Span::mixed_site() => $($tt)*)
174 }
175}