1use proc_macro2::{Spacing, Span};
2use quote::quote;
3
4use crate::{tokens::LiteralKind, Delimiter, MacroStream, ParserOutput, Pattern, Token};
5
6pub trait Repr {
8 fn repr(&self, name: &str) -> MacroStream;
9}
10
11impl Repr for Token {
12 fn repr(&self, name: &str) -> MacroStream {
13 match self {
14 Self::Group {
15 delimiter,
16 stream,
17 span,
18 } => {
19 let delimiter = delimiter.repr(name);
20 let stream = stream.repr(name);
21 let span = span.repr(name);
22 quote! {
23 macros_utils::Token::Group {
24 delimiter: #delimiter,
25 stream: #stream,
26 span: #span,
27 }
28 }
29 },
30 Self::Ident { name: n, span } => {
31 let span = span.repr(name);
32 quote! {
33 macros_utils::Token::Ident {
34 name: #n.to_string(),
35 span: #span,
36 }
37 }
38 },
39 Self::Literal {
40 kind,
41 value,
42 span,
43 suffix,
44 ..
45 } => {
46 let kind = kind.repr(name);
47 let span = span.repr(name);
48 quote! {
49 macros_utils::Token::Literal {
50 kind: #kind,
51 value: #value.to_string(),
52 span: #span,
53 suffix: #suffix.to_string(),
54 token: None,
55 }
56 }
57 },
58 Self::Punctuation {
59 value,
60 spacing,
61 span,
62 } => {
63 let spacing = spacing.repr(name);
64 let span = span.repr(name);
65 quote! {
66 macros_utils::Token::Punctuation {
67 value: #value,
68 spacing: #spacing,
69 span: #span,
70 }
71 }
72 },
73 }
74 .into()
75 }
76}
77
78impl Repr for Delimiter {
79 fn repr(&self, _: &str) -> MacroStream {
80 match self {
81 Delimiter::Brace => quote! { macros_utils::Delimiter::Brace },
82 Delimiter::Bracket => quote! { macros_utils::Delimiter::Bracket },
83 Delimiter::Parenthesis => quote! { macros_utils::Delimiter::Parenthesis },
84 Delimiter::None => quote! { macros_utils::Delimiter::None },
85 }
86 .into()
87 }
88}
89
90impl Repr for MacroStream {
91 fn repr(&self, name: &str) -> MacroStream {
92 let tokens = self.stream.iter().map(|token| token.repr(name));
93 quote! {
94 macros_utils::MacroStream::new(vec![
95 #(#tokens),*
96 ])
97 }
98 .into()
99 }
100}
101
102impl Repr for Span {
103 fn repr(&self, _: &str) -> MacroStream {
104 quote! {
105 macros_utils::call_site()
106 }
107 .into()
108 }
109}
110
111impl Repr for LiteralKind {
112 fn repr(&self, _: &str) -> MacroStream {
113 match self {
114 Self::Byte => quote! { macros_utils::LiteralKind::Byte },
115 Self::Char => quote! { macros_utils::LiteralKind::Char },
116 Self::Float => quote! { macros_utils::LiteralKind::Float },
117 Self::Integer => quote! { macros_utils::LiteralKind::Integer },
118 Self::Str => quote! { macros_utils::LiteralKind::Str },
119 Self::StrRaw(h) => quote! { macros_utils::LiteralKind::StrRaw(#h) },
120 Self::ByteStr => quote! { macros_utils::LiteralKind::ByteStr },
121 Self::ByteStrRaw(h) => quote! { macros_utils::LiteralKind::ByteStrRaw(#h) },
122 }
123 .into()
124 }
125}
126
127impl Repr for Spacing {
128 fn repr(&self, _: &str) -> MacroStream {
129 match self {
130 Self::Alone => quote! { macros_utils::Spacing::Alone },
131 Self::Joint => quote! { macros_utils::Spacing::Joint },
132 }
133 .into()
134 }
135}
136
137impl<T> Repr for Pattern<T>
138where
139 T: ToOwned<Owned = T> + ParserOutput,
140{
141 fn repr(&self, name: &str) -> MacroStream {
142 let type_name = Token::Ident {
143 name: name.to_string(),
144 span: Span::call_site(),
145 };
146 match self {
147 Self::Any => quote! { macros_utils::Pattern::<#type_name>::Any },
148 Self::Choice(patterns) => {
149 let patterns = patterns.repr(name);
150 quote! {
151 macros_utils::Pattern::<#type_name>::Choice(#patterns)
152 }
153 },
154 Self::Group(delimiter, pattern) => {
155 let delimiter = delimiter.repr(name);
156 let patterns = pattern.repr(name);
157 quote! {
158 macros_utils::Pattern::<#type_name>::Group(#delimiter, #patterns)
159 }
160 },
161 Self::OneOrMore(pattern, greedy) => {
162 let pattern = pattern.repr(name);
163 quote! {
164 macros_utils::Pattern::<#type_name>::OneOrMore(#pattern, #greedy)
165 }
166 },
167 Self::Optional(pattern) => {
168 let pattern = pattern.repr(name);
169 quote! {
170 macros_utils::Pattern::<#type_name>::Optional(#pattern)
171 }
172 },
173 Self::Parameter(pattern, parameter) => {
174 let pattern = pattern.repr(name);
175 quote! {
176 macros_utils::Pattern::<#type_name>::Parameter(#pattern, #parameter.into())
177 }
178 },
179 Self::Token(token) => {
180 let token = token.repr(name);
181 quote! {
182 macros_utils::Pattern::<#type_name>::Token(#token)
183 }
184 },
185 Self::Validator(stream, _) => {
186 let func = match stream {
187 Some(s) => quote! { Some({#s}) },
188 None => quote! { None },
189 };
190 quote! {
191 macros_utils::Pattern::<#type_name>::Validator(None, #func)
192 }
193 },
194 Self::ZeroOrMore(pattern, greedy) => {
195 let pattern = pattern.repr(name);
196 quote! {
197 macros_utils::Pattern::<#type_name>::ZeroOrMore(#pattern, #greedy)
198 }
199 },
200 }
201 .into()
202 }
203}
204
205impl<T> Repr for Vec<T>
206where
207 T: Repr,
208{
209 fn repr(&self, name: &str) -> MacroStream {
210 let tokens = self.iter().map(|token| token.repr(name));
211 quote! {
212 vec![
213 #(#tokens),*
214 ]
215 }
216 .into()
217 }
218}
219
220impl<T> Repr for Option<T>
221where
222 T: Repr,
223{
224 fn repr(&self, name: &str) -> MacroStream {
225 match self {
226 Some(value) => {
227 let value = value.repr(name);
228 quote! {
229 Some(#value)
230 }
231 },
232 None => quote! { None },
233 }
234 .into()
235 }
236}
237
238impl<T> Repr for &T
239where
240 T: Repr,
241{
242 fn repr(&self, name: &str) -> MacroStream {
243 (*self).repr(name)
244 }
245}