moxy_token/bridge/
proc_macro.rs1use crate::parser::ParseError;
2use crate::span::fallback;
3use crate::{Delim, Group, Ident, Keyword, Lit, Spacing, Span, ToTokens, TokenStream, TokenTree};
4
5impl From<proc_macro::LexError> for ParseError {
8 fn from(e: proc_macro::LexError) -> Self {
9 Self::new(Span::default(), e)
10 }
11}
12
13impl From<proc_macro::Span> for fallback::Span {
16 fn from(#[allow(unused)] value: proc_macro::Span) -> Self {
17 #[cfg(nightly)]
18 {
19 let r = value.byte_range();
20 Self::new(r.start as u32, r.end as u32)
21 }
22
23 #[cfg(not(nightly))]
24 {
25 Self::default()
26 }
27 }
28}
29
30impl From<fallback::Span> for proc_macro::Span {
31 fn from(_value: fallback::Span) -> Self {
32 Self::call_site()
33 }
34}
35
36impl From<proc_macro::Span> for Span {
39 #[inline]
40 fn from(value: proc_macro::Span) -> Self {
41 Self::Compiler(value)
42 }
43}
44
45impl From<Span> for proc_macro::Span {
46 fn from(value: Span) -> Self {
47 match value {
48 Span::Compiler(s) => s,
49 Span::Fallback(_) => Self::call_site(),
50 }
51 }
52}
53
54#[cfg(nightly)]
55impl proc_macro::MultiSpan for Span {
56 fn into_spans(self) -> Vec<proc_macro::Span> {
57 match self {
58 Self::Compiler(s) => vec![s],
59 Self::Fallback(_) => vec![proc_macro::Span::call_site()],
60 }
61 }
62}
63
64impl From<proc_macro::Delimiter> for Delim {
67 #[inline]
68 fn from(value: proc_macro::Delimiter) -> Self {
69 match value {
70 proc_macro::Delimiter::Parenthesis => Self::Paren,
71 proc_macro::Delimiter::Brace => Self::Brace,
72 proc_macro::Delimiter::Bracket => Self::Bracket,
73 proc_macro::Delimiter::None => Self::None,
74 }
75 }
76}
77
78impl From<Delim> for proc_macro::Delimiter {
79 #[inline]
80 fn from(value: Delim) -> Self {
81 match value {
82 Delim::Paren => Self::Parenthesis,
83 Delim::Brace => Self::Brace,
84 Delim::Bracket => Self::Bracket,
85 Delim::None => Self::None,
86 }
87 }
88}
89
90impl From<proc_macro::Spacing> for Spacing {
93 #[inline]
94 fn from(value: proc_macro::Spacing) -> Self {
95 match value {
96 proc_macro::Spacing::Alone => Self::Alone,
97 proc_macro::Spacing::Joint => Self::Joint,
98 }
99 }
100}
101
102impl From<Spacing> for proc_macro::Spacing {
103 #[inline]
104 fn from(value: Spacing) -> Self {
105 match value {
106 Spacing::Alone => Self::Alone,
107 Spacing::Joint => Self::Joint,
108 }
109 }
110}
111
112impl From<proc_macro::Ident> for Ident {
115 #[inline]
116 fn from(value: proc_macro::Ident) -> Self {
117 Self::new(value.to_string()).with_span(value.span().into())
118 }
119}
120
121impl From<Ident> for proc_macro::Ident {
122 fn from(value: Ident) -> Self {
123 let span: proc_macro::Span = value.span().into();
124 let name = value.text();
125
126 match name.strip_prefix("r#") {
127 Some(raw) => Self::new_raw(raw, span),
128 None => Self::new(name, span),
129 }
130 }
131}
132
133impl From<proc_macro::Literal> for Lit {
136 fn from(value: proc_macro::Literal) -> Self {
137 Self::from_repr(&value.to_string(), value.span().into())
138 }
139}
140
141impl From<Lit> for proc_macro::Literal {
142 fn from(value: Lit) -> Self {
143 let repr = value.repr();
144 let mut lit = repr.parse().unwrap_or_else(|_| Self::string(repr));
145
146 lit.set_span(value.span().into());
147 lit
148 }
149}
150
151impl From<proc_macro::Group> for Group {
154 #[inline]
155 fn from(value: proc_macro::Group) -> Self {
156 use crate::span::DelimSpan;
157 let mut group = Self::new(value.delimiter().into(), value.stream().into());
158 group.set_span(DelimSpan::new(value.span_open().into(), value.span_close().into()));
159 group
160 }
161}
162
163impl From<Group> for proc_macro::Group {
164 #[inline]
165 fn from(value: Group) -> Self {
166 let span = value.span().span().into();
167 let mut group = Self::new(value.delim.into(), value.tokens.into());
168 group.set_span(span);
169 group
170 }
171}
172
173impl ToTokens<TokenStream> for proc_macro::TokenTree {
176 fn to_tokens(&self, tokens: &mut TokenStream) {
177 match self {
178 Self::Ident(v) => {
179 let tt = match Keyword::from_str(&v.to_string(), v.span().into()) {
180 Some(kw) => TokenTree::Keyword(kw),
181 None => TokenTree::Ident(v.clone().into()),
182 };
183 tokens.extend_one(tt)
184 }
185 Self::Literal(v) => tokens.extend_one(TokenTree::Literal(v.clone().into())),
186 Self::Group(v) => tokens.extend_one(TokenTree::Group(v.clone().into())),
187 Self::Punct(p) => crate::scan_puncts_spanned(&[(p.as_char(), p.span().into())], tokens),
188 }
189 }
190}
191
192impl ToTokens<TokenStream> for proc_macro::TokenStream {
193 fn to_tokens(&self, tokens: &mut TokenStream) {
194 let mut punct_run: Vec<(char, Span)> = Vec::new();
195
196 for tt in self.clone() {
197 match tt {
198 proc_macro::TokenTree::Punct(p) => punct_run.push((p.as_char(), p.span().into())),
199 other => {
200 if !punct_run.is_empty() {
201 crate::scan_puncts_spanned(&punct_run, tokens);
202 punct_run.clear();
203 }
204 other.to_tokens(tokens);
205 }
206 }
207 }
208
209 if !punct_run.is_empty() {
210 crate::scan_puncts_spanned(&punct_run, tokens);
211 }
212 }
213}
214
215impl ToTokens<proc_macro::TokenStream> for TokenTree {
216 fn to_tokens(&self, out: &mut proc_macro::TokenStream) {
217 match self {
218 Self::Group(g) => out.extend(vec![proc_macro::TokenTree::Group(g.clone().into())]),
219 Self::Ident(v) => out.extend(vec![proc_macro::TokenTree::Ident(v.clone().into())]),
220 Self::Keyword(kw) => {
221 let id = proc_macro::Ident::new(kw.as_str(), kw.span().into());
222 out.extend(vec![proc_macro::TokenTree::Ident(id)])
223 }
224 Self::Literal(v) => out.extend(vec![proc_macro::TokenTree::Literal(v.clone().into())]),
225 Self::Punct(op) => {
226 let text = op.as_str();
227 let span: proc_macro::Span = op.span().into();
228 let last = text.chars().count() - 1;
229 let joint_last = text == "'";
230
231 for (i, ch) in text.chars().enumerate() {
232 let spacing = if i == last && !joint_last {
233 proc_macro::Spacing::Alone
234 } else {
235 proc_macro::Spacing::Joint
236 };
237
238 let mut p = proc_macro::Punct::new(ch, spacing);
239 p.set_span(span);
240 out.extend(vec![proc_macro::TokenTree::Punct(p)]);
241 }
242 }
243 }
244 }
245}
246
247impl ToTokens<proc_macro::TokenStream> for TokenStream {
248 fn to_tokens(&self, out: &mut proc_macro::TokenStream) {
249 for t in self.iter() {
250 t.to_tokens(out);
251 }
252 }
253}
254
255impl From<proc_macro::TokenStream> for TokenStream {
256 fn from(value: proc_macro::TokenStream) -> Self {
257 let mut out = Self::new();
258 value.to_tokens(&mut out);
259 out
260 }
261}
262
263impl From<TokenStream> for proc_macro::TokenStream {
264 fn from(value: TokenStream) -> Self {
265 let mut out = Self::new();
266 for t in value.iter() {
267 t.to_tokens(&mut out);
268 }
269 out
270 }
271}