1macro_rules! quote {
2 () => (::proc_macro::TokenStream::new());
3 ($($x:tt)*) => {{
4 let mut ts = ::proc_macro::TokenStream::new();
5 let ts_mut = &mut ts;
6 quote_inner!(ts_mut $($x)*);
7 ts
8 }};
9}
10
11#[cfg(any(feature = "formatting", feature = "parsing"))]
12macro_rules! quote_append {
13 ($ts:ident $($x:tt)*) => {{
14 quote_inner!($ts $($x)*);
15 }};
16}
17
18macro_rules! quote_group {
19 ({ $($x:tt)* }) => {
20 ::proc_macro::TokenTree::Group(::proc_macro::Group::new(
21 ::proc_macro::Delimiter::Brace,
22 quote!($($x)*)
23 ))
24 };
25}
26
27macro_rules! sym {
28 ($ts:ident $x:tt $y:tt) => {
29 $ts.extend([
30 ::proc_macro::TokenTree::from(::proc_macro::Punct::new(
31 $x,
32 ::proc_macro::Spacing::Joint,
33 )),
34 ::proc_macro::TokenTree::from(::proc_macro::Punct::new(
35 $y,
36 ::proc_macro::Spacing::Alone,
37 )),
38 ]);
39 };
40 ($ts:ident $x:tt) => {
41 $ts.extend([::proc_macro::TokenTree::from(::proc_macro::Punct::new(
42 $x,
43 ::proc_macro::Spacing::Alone,
44 ))]);
45 };
46}
47
48#[allow(unused_macro_rules)] macro_rules! quote_inner {
50 ($ts:ident) => {};
52
53 ($ts:ident :: $($tail:tt)*) => { sym!($ts ':' ':'); quote_inner!($ts $($tail)*); };
55 ($ts:ident : $($tail:tt)*) => { sym!($ts ':'); quote_inner!($ts $($tail)*); };
56 ($ts:ident = $($tail:tt)*) => { sym!($ts '='); quote_inner!($ts $($tail)*); };
57 ($ts:ident ; $($tail:tt)*) => { sym!($ts ';'); quote_inner!($ts $($tail)*); };
58 ($ts:ident , $($tail:tt)*) => { sym!($ts ','); quote_inner!($ts $($tail)*); };
59 ($ts:ident . $($tail:tt)*) => { sym!($ts '.'); quote_inner!($ts $($tail)*); };
60 ($ts:ident & $($tail:tt)*) => { sym!($ts '&'); quote_inner!($ts $($tail)*); };
61 ($ts:ident < $($tail:tt)*) => { sym!($ts '<'); quote_inner!($ts $($tail)*); };
62 ($ts:ident >> $($tail:tt)*) => { sym!($ts '>' '>'); quote_inner!($ts $($tail)*); };
63 ($ts:ident > $($tail:tt)*) => { sym!($ts '>'); quote_inner!($ts $($tail)*); };
64 ($ts:ident -> $($tail:tt)*) => { sym!($ts '-' '>'); quote_inner!($ts $($tail)*); };
65 ($ts:ident ? $($tail:tt)*) => { sym!($ts '?'); quote_inner!($ts $($tail)*); };
66 ($ts:ident ! $($tail:tt)*) => { sym!($ts '!'); quote_inner!($ts $($tail)*); };
67 ($ts:ident | $($tail:tt)*) => { sym!($ts '|'); quote_inner!($ts $($tail)*); };
68 ($ts:ident * $($tail:tt)*) => { sym!($ts '*'); quote_inner!($ts $($tail)*); };
69 ($ts:ident + $($tail:tt)*) => { sym!($ts '+'); quote_inner!($ts $($tail)*); };
70
71 ($ts:ident $i:ident $($tail:tt)*) => {
73 $ts.extend([::proc_macro::TokenTree::from(::proc_macro::Ident::new(
74 &stringify!($i),
75 ::proc_macro::Span::mixed_site(),
76 ))]);
77 quote_inner!($ts $($tail)*);
78 };
79
80 ($ts:ident 0 $($tail:tt)*) => {
82 $ts.extend([::proc_macro::TokenTree::from(::proc_macro::Literal::usize_unsuffixed(0))]);
83 quote_inner!($ts $($tail)*);
84 };
85 ($ts:ident $l:literal $($tail:tt)*) => {
86 $ts.extend([::proc_macro::TokenTree::from(::proc_macro::Literal::string(&$l))]);
87 quote_inner!($ts $($tail)*);
88 };
89
90 ($ts:ident $l:lifetime $($tail:tt)*) => {
92 $ts.extend([
93 ::proc_macro::TokenTree::from(
94 ::proc_macro::Punct::new('\'', ::proc_macro::Spacing::Joint)
95 ),
96 ::proc_macro::TokenTree::from(::proc_macro::Ident::new(
97 stringify!($l).trim_start_matches(|c| c == '\''),
98 ::proc_macro::Span::mixed_site(),
99 )),
100 ]);
101 quote_inner!($ts $($tail)*);
102 };
103
104 ($ts:ident #[$($inner:tt)*] $($tail:tt)*) => {
106 $ts.extend([
107 ::proc_macro::TokenTree::from(
108 ::proc_macro::Punct::new('#', ::proc_macro::Spacing::Alone)
109 ),
110 ::proc_macro::TokenTree::Group(::proc_macro::Group::new(
111 ::proc_macro::Delimiter::Bracket,
112 quote!($($inner)*)
113 )),
114 ]);
115 quote_inner!($ts $($tail)*);
116 };
117
118 ($ts:ident ($($inner:tt)*) $($tail:tt)*) => {
120 $ts.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
121 ::proc_macro::Delimiter::Parenthesis,
122 quote!($($inner)*)
123 ))]);
124 quote_inner!($ts $($tail)*);
125 };
126 ($ts:ident [$($inner:tt)*] $($tail:tt)*) => {
127 $ts.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
128 ::proc_macro::Delimiter::Bracket,
129 quote!($($inner)*)
130 ))]);
131 quote_inner!($ts $($tail)*);
132 };
133 ($ts:ident {$($inner:tt)*} $($tail:tt)*) => {
134 $ts.extend([::proc_macro::TokenTree::Group(::proc_macro::Group::new(
135 ::proc_macro::Delimiter::Brace,
136 quote!($($inner)*)
137 ))]);
138 quote_inner!($ts $($tail)*);
139 };
140
141 ($ts:ident #($e:expr) $($tail:tt)*) => {
144 $ts.extend([$crate::to_tokens::ToTokenTree::into_token_tree($e)]);
145 quote_inner!($ts $($tail)*);
146 };
147 ($ts:ident #S($e:expr) $($tail:tt)*) => {
149 $crate::to_tokens::ToTokenStream::append_to($e, $ts);
150 quote_inner!($ts $($tail)*);
151 };
152}