1use from_attr_core::Array;
2use proc_macro2::{Group, Literal, Punct, TokenTree};
3use syn::{
4 parse_quote,
5 token::{
6 Abstract, And, AndAnd, AndEq, As, Async, At, Auto, Await, Become, Break, Caret, CaretEq,
7 Colon, Comma, Const, Continue, Crate, Do, Dollar, Dot, DotDot, DotDotDot, DotDotEq, Dyn,
8 Else, Enum, Eq, EqEq, Extern, FatArrow, Final, Fn, For, Ge, Gt, If, Impl, In, LArrow, Le,
9 Let, Loop, Lt, Match, Minus, MinusEq, Mod, Move, Mut, Ne, Not, Or, OrEq, OrOr, Override,
10 PathSep, Percent, PercentEq, Plus, PlusEq, Pound, Priv, Pub, Question, RArrow, Ref, Return,
11 SelfType, SelfValue, Semi, Shl, ShlEq, Shr, ShrEq, Slash, SlashEq, Star, StarEq, Static,
12 Struct, Super, Tilde, Trait, Try, Typeof, Underscore, Union, Unsafe, Unsized, Use, Virtual,
13 Where, While, Yield,
14 },
15 Abi, AngleBracketedGenericArguments, BareFnArg, BinOp, BoundLifetimes, ConstParam, Constraint,
16 DeriveInput, Expr, ExprArray, ExprAssign, ExprAsync, ExprBinary, ExprBlock, ExprBreak,
17 ExprCall, ExprCast, ExprClosure, ExprContinue, ExprField, ExprForLoop, ExprIf, ExprIndex,
18 ExprLet, ExprLit, ExprLoop, ExprMacro, ExprMatch, ExprMethodCall, ExprParen, ExprPath,
19 ExprRange, ExprReference, ExprRepeat, ExprReturn, ExprStruct, ExprTry, ExprTryBlock, ExprTuple,
20 ExprUnary, ExprUnsafe, ExprWhile, ExprYield, FieldValue, FieldsNamed, FieldsUnnamed,
21 GenericArgument, GenericParam, Generics, Ident, Index, Lifetime, Lit, LitBool, LitByteStr,
22 LitChar, LitFloat, LitInt, LitStr, Member, Meta, MetaList, MetaNameValue,
23 ParenthesizedGenericArguments, Path, PathSegment, ReturnType, TraitBound, TraitBoundModifier,
24 Type, TypeArray, TypeBareFn, TypeGroup, TypeImplTrait, TypeInfer, TypeMacro, TypeNever,
25 TypeParam, TypeParamBound, TypeParen, TypePath, TypePtr, TypeReference, TypeSlice,
26 TypeTraitObject, TypeTuple, UnOp, Variant, Visibility, WhereClause, WherePredicate,
27};
28
29use crate::PathValue;
30
31pub trait ConvertParsed: Sized {
39 type Type;
41
42 fn convert(path_value: PathValue<Self::Type>) -> syn::Result<Self>;
44
45 fn default() -> Option<Self> {
47 None
48 }
49
50 fn flag() -> Option<Self::Type> {
52 None
53 }
54}
55
56impl<T> ConvertParsed for Option<T>
57where
58 T: ConvertParsed,
59{
60 type Type = T::Type;
61
62 fn convert(path_value: PathValue<Self::Type>) -> syn::Result<Self> {
63 Ok(Some(T::convert(path_value)?))
64 }
65
66 fn default() -> Option<Self> {
67 Some(None)
68 }
69
70 fn flag() -> Option<Self::Type> {
71 T::flag()
72 }
73}
74
75impl<T> ConvertParsed for Vec<T>
76where
77 T: ConvertParsed,
78{
79 type Type = Array<T::Type>;
80
81 fn convert(path_value: PathValue<Self::Type>) -> syn::Result<Self> {
82 let PathValue { path, value } = path_value;
83
84 let mut elems = Vec::new();
85 let mut errors = Vec::new();
86
87 value
88 .elems
89 .into_iter()
90 .for_each(|value| match T::convert(PathValue { path, value }) {
91 Ok(o) => elems.push(o),
92 Err(e) => errors.push(e),
93 });
94
95 match errors.into_iter().reduce(|mut a, b| {
96 a.combine(b);
97 a
98 }) {
99 Some(e) => Err(e),
100 None => Ok(elems),
101 }
102 }
103
104 fn default() -> Option<Self> {
105 Some(Vec::new())
106 }
107}
108
109impl ConvertParsed for bool {
110 type Type = LitBool;
111
112 fn convert(path_value: PathValue<Self::Type>) -> syn::Result<Self> {
113 Ok(path_value.value.value)
114 }
115
116 fn default() -> Option<Self> {
117 Some(false)
118 }
119
120 fn flag() -> Option<Self::Type> {
121 Some(parse_quote!(true))
122 }
123}
124
125macro_rules! get_value {
126 ($from:path => $to:path > $get:path) => {
127 impl ConvertParsed for $to {
128 type Type = $from;
129
130 fn convert(path_value: PathValue<$from>) -> syn::Result<$to> {
131 Ok($get(&path_value.value))
132 }
133 }
134 };
135}
136
137get_value!(LitStr => String > LitStr::value);
138get_value!(LitChar => char > LitChar::value);
139
140macro_rules! parse_value {
141 ($from:path => $($to:path),+ > $parse:path) => {
142 $(
143 impl ConvertParsed for $to {
144 type Type = $from;
145
146 fn convert(path_value: PathValue<$from>) -> syn::Result<$to> {
147 $parse(&path_value.value)
148 }
149 }
150 )*
151 };
152}
153
154parse_value!(LitInt => u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize > LitInt::base10_parse);
155parse_value!(LitFloat => f32, f64 > LitFloat::base10_parse);
156
157macro_rules! convert_parsed {
158 ($($type:ty),* $(,)?) => {
159 $(
160 impl ConvertParsed for $type {
161 type Type = $type;
162
163 fn convert(path_value: PathValue<Self>) -> syn::Result<Self> {
164 Ok(path_value.value)
165 }
166 }
167 )*
168 };
169}
170
171convert_parsed![
172 Abi,
173 Abstract,
174 And,
175 AndAnd,
176 AndEq,
177 AngleBracketedGenericArguments,
178 As,
179 Async,
180 At,
181 Auto,
182 Await,
183 BareFnArg,
184 Become,
185 BinOp,
186 BoundLifetimes,
187 Break,
188 Caret,
189 CaretEq,
190 Colon,
191 Comma,
192 Const,
193 ConstParam,
194 Constraint,
195 Continue,
196 Crate,
197 DeriveInput,
198 Do,
199 Dollar,
200 Dot,
201 DotDot,
202 DotDotDot,
203 DotDotEq,
204 Dyn,
205 Else,
206 Enum,
207 Eq,
208 EqEq,
209 Expr,
210 ExprArray,
211 ExprAssign,
212 ExprAsync,
213 ExprBinary,
214 ExprBlock,
215 ExprBreak,
216 ExprCall,
217 ExprCast,
218 ExprClosure,
219 ExprContinue,
220 ExprField,
221 ExprForLoop,
222 ExprIf,
223 ExprIndex,
224 ExprLet,
225 ExprLit,
226 ExprLoop,
227 ExprMacro,
228 ExprMatch,
229 ExprMethodCall,
230 ExprParen,
231 ExprPath,
232 ExprRange,
233 ExprReference,
234 ExprRepeat,
235 ExprReturn,
236 ExprStruct,
237 ExprTry,
238 ExprTryBlock,
239 ExprTuple,
240 ExprUnary,
241 ExprUnsafe,
242 ExprWhile,
243 ExprYield,
244 Extern,
245 FatArrow,
246 FieldValue,
247 FieldsNamed,
248 FieldsUnnamed,
249 Final,
250 Fn,
251 For,
252 Ge,
253 GenericArgument,
254 GenericParam,
255 Generics,
256 Group,
257 Gt,
258 Ident,
259 If,
260 Impl,
261 In,
262 Index,
263 LArrow,
264 Le,
265 Let,
266 Lifetime,
267 Lit,
268 LitBool,
269 LitByteStr,
270 LitChar,
271 LitFloat,
272 LitInt,
273 LitStr,
274 Literal,
275 Loop,
276 Lt,
277 Match,
278 Member,
279 Meta,
280 MetaList,
281 MetaNameValue,
282 Minus,
283 MinusEq,
284 Mod,
285 Move,
286 Mut,
287 Ne,
288 Not,
289 Or,
290 OrEq,
291 OrOr,
292 Override,
293 ParenthesizedGenericArguments,
294 Path,
295 PathSegment,
296 PathSep,
297 Percent,
298 PercentEq,
299 Plus,
300 PlusEq,
301 Pound,
302 Priv,
303 Pub,
304 Punct,
305 Question,
306 RArrow,
307 Ref,
308 Return,
309 ReturnType,
310 SelfType,
311 SelfValue,
312 Semi,
313 Shl,
314 ShlEq,
315 Shr,
316 ShrEq,
317 Slash,
318 SlashEq,
319 Star,
320 StarEq,
321 Static,
322 Struct,
323 Super,
324 Tilde,
325 TokenTree,
326 Trait,
327 TraitBound,
328 TraitBoundModifier,
329 Try,
330 TypeArray,
331 TypeBareFn,
332 TypeGroup,
333 TypeImplTrait,
334 TypeInfer,
335 TypeMacro,
336 TypeNever,
337 TypeParam,
338 TypeParamBound,
339 TypeParen,
340 TypePath,
341 TypePtr,
342 TypeReference,
343 TypeSlice,
344 TypeTraitObject,
345 TypeTuple,
346 Typeof,
347 UnOp,
348 Underscore,
349 Union,
350 Unsafe,
351 Unsized,
352 Use,
353 Variant,
354 Virtual,
355 Visibility,
356 Where,
357 WhereClause,
358 WherePredicate,
359 While,
360 Yield,
361 syn::Macro,
362 syn::token::Box,
363 syn::token::Default,
364 syn::token::Macro,
365 syn::token::Type,
366 Type,
367];
368
369#[cfg_attr(docsrs, doc(cfg(feature = "syn-full")))]
370#[cfg(feature = "syn-full")]
371mod syn_full {
372 use syn::{
373 Arm, Block, File, FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic,
374 ForeignItemType, ImplItem, ImplItemConst, ImplItemMacro, ImplItemType, Item, ItemConst,
375 ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod,
376 ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Label,
377 Pat, RangeLimits, Receiver, Signature, Stmt, TraitItem, TraitItemConst, TraitItemMacro,
378 TraitItemType, UseTree,
379 };
380
381 use super::*;
382
383 convert_parsed![
384 Block,
385 File,
386 FnArg,
387 ForeignItem,
388 ForeignItemFn,
389 ForeignItemMacro,
390 ForeignItemStatic,
391 ForeignItemType,
392 ImplItem,
393 ImplItemConst,
394 ImplItemMacro,
395 ImplItemType,
396 Item,
397 ItemConst,
398 ItemEnum,
399 ItemExternCrate,
400 ItemFn,
401 ItemForeignMod,
402 ItemImpl,
403 ItemMacro,
404 ItemMod,
405 ItemStatic,
406 ItemStruct,
407 ItemTrait,
408 ItemTraitAlias,
409 ItemType,
410 ItemUnion,
411 ItemUse,
412 Label,
413 Pat,
414 RangeLimits,
415 Receiver,
416 Signature,
417 Stmt,
418 TraitItem,
419 TraitItemConst,
420 TraitItemMacro,
421 TraitItemType,
422 UseTree,
423 Arm,
424 ];
425}