typed_quote/tokens/
puncts.rs1use super::*;
2
3#[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
4trait Puncts<TS> {
5 type Puncts;
6 fn puncts(span: impl MaybeSpan) -> Self::Puncts;
7}
8
9#[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
10macro_rules! puncts {
11 (($p0:literal, $p1:literal, $p2:literal $(,)?) $span:ident) => {
12 puncts![@[$p0 $p1][$p2] $span]
13 };
14 (($p0:literal, $p1:literal $(,)?) $span:ident) => {
15 puncts![@[$p0][$p1] $span]
16 };
17 (@[$($ch:literal)+][$last:literal] $span:ident) => {
18 puncts![
19 @@[
20 $(($ch Joint))+
21 ($last Alone)
22 ]
23 $span
24 ]
25 };
26 (@@[$(($ch:literal $spacing:ident))+] $span:ident) => {
27 [$(
28 pm::TokenTree::Punct(
29 (
30 pm::Punct::new($ch, pm::Spacing::$spacing),
31 $span,
32 ).into_st()
33 ),
34 )+]
35 };
36}
37
38#[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
39macro_rules! count_literals {
40 ($($a:literal),+ $(,)?) => {
41 const { [$($a,)+].len() }
42 };
43}
44
45macro_rules! define_struct {
46 ({$(#$attrs:tt)*} $PunctGroup:ident) => {
47 $(#$attrs)*
48 pub struct $PunctGroup<S: MaybeSpan>(pub S);
49 };
50}
51
52macro_rules! define_structs {
53 ($attrs:tt [$($PunctGroup:ident)*]) => {
54 $(
55 define_struct! {
56 $attrs
57 $PunctGroup
58 }
59 )*
60 };
61}
62
63macro_rules! imp {
64 ({
65 $(#$attrs:tt)*
66 [$(
67 $PunctGroup:ident $chars:tt
68 ),+ $(,)?];
69
70 use $PS:ident;
71
72 $($imp:tt)*
73 }) => {
74 define_structs! {
75 {
76 $(#$attrs)*
77 }
78 [$($PunctGroup)+]
79 }
80
81 $(
82 crate::impl_many!({
83 {
84 #[cfg(feature = "proc-macro")]
85 {
86 use proc_macro as pm;
87 }
88 #[cfg(feature = "proc-macro2")]
89 {
90 use proc_macro2 as pm;
91 }
92 }
93
94 impl<S: MaybeSpan> Puncts<pm::TokenStream> for $PunctGroup<S> {
95 type Puncts = [pm::TokenTree; count_literals! $chars];
96 fn puncts(span: impl MaybeSpan) -> Self::Puncts {
97 puncts!($chars span)
98 }
99 }
100 });
101 )+
102
103 imp! {
104 @[$($PunctGroup)+]
105 $PS
106 [$($imp)*]
107 }
108 };
109 (
110 @[$($PunctGroup:ident)+]
111 $PS:ident
112 $imp:tt
113 ) => {
114 $(
115 const _: () = {
116 use $PunctGroup as $PS;
117
118 crate::expand_or! {$imp}
119 };
120 )+
121 };
122}
123
124imp!({
125 #[derive(Debug, Clone, Copy)]
126 [
127 Colon2(':', ':'),
128 AddEq('+', '='),
129 AndAnd('&', '&'),
130 AndEq('&', '='),
131 CaretEq('^', '='),
132 DivEq('/', '='),
133 Dot2('.', '.'),
134 Dot3('.', '.', '.'),
135 DotDotEq('.', '.', '='),
136 EqEq('=', '='),
137 Ge('>', '='),
138 Le('<', '='),
139 MulEq('*', '='),
140 Ne('!', '='),
141 OrEq('|', '='),
142 OrOr('|', '|'),
143 RArrow('-', '>'),
144 LArrow('<', '-'),
145 RemEq('%', '='),
146 FatArrow('=', '>'),
147 Shl('<', '<'),
148 ShlEq('<', '<', '='),
149 Shr('>', '>'),
150 ShrEq('>', '>', '='),
151 SubEq('-', '='),
152 ];
153 use PS;
154
155 impl<S: MaybeSpan> sealed::IntoTokens for PS<S> {}
156 impl<S: MaybeSpan> IntoTokens for PS<S> {
157 crate::impl_into_tokens!(
158 |self, ts| ts.extend(<Self as Puncts<pm::TokenStream>>::puncts(self.0)),
159 pm::TokenStream::from_iter(<Self as Puncts<pm::TokenStream>>::puncts(self.0)),
160 );
161 }
162
163 impl<S: MaybeSpan> sealed::ToTokens for PS<S> {}
164 impl<S: MaybeSpan> ToTokens for PS<S> {
165 crate::impl_to_tokens! {copy}
166 }
167
168 impl<SO: MaybeSpan> sealed::WithSpan for PS<SO> {}
169 impl<SO: MaybeSpan> WithSpan for PS<SO> {
170 type WithDefaultSpan<S: crate::Span> = PS<SO::WithDefaultSpan<S>>;
171
172 fn with_default_span<S: crate::Span>(self, span: S) -> Self::WithDefaultSpan<S> {
173 PS(self.0.with_default_span(span))
174 }
175
176 type WithReplacedSpan<S: crate::Span> = PS<SO::WithReplacedSpan<S>>;
177
178 fn with_replaced_span<S: crate::Span>(self, span: S) -> Self::WithReplacedSpan<S> {
179 PS(self.0.with_replaced_span(span))
180 }
181 }
182
183 impl<SO: MaybeSpan> sealed::RefWithSpan for PS<SO> {}
184 impl<SO: MaybeSpan> RefWithSpan for PS<SO> {
185 crate::impl_ref_with_span! {copy}
186 }
187});