1use proc_macro2::TokenStream;
2use quote::{quote, ToTokens};
3use syn::Ident;
4
5use crate::codegen::{ExtractAttribute, ForwardAttrs, OuterFromImpl, TraitImpl};
6use crate::util::PathList;
7
8pub struct FromTypeParamImpl<'a> {
9 pub base: TraitImpl<'a>,
10 pub ident: Option<&'a Ident>,
11 pub bounds: Option<&'a Ident>,
12 pub default: Option<&'a Ident>,
13 pub attr_names: &'a PathList,
14 pub forward_attrs: ForwardAttrs<'a>,
15 pub from_ident: bool,
16}
17
18impl ToTokens for FromTypeParamImpl<'_> {
19 fn to_tokens(&self, tokens: &mut TokenStream) {
20 let input = self.param_name();
21
22 let error_declaration = self.base.declare_errors();
23 let grab_attrs = self.extractor();
24 let require_fields = self.base.require_fields();
25 let error_check = self.base.check_errors();
26
27 let default = if self.from_ident {
28 quote!(let __default: Self = ::darling::export::From::from(#input.ident.clone());)
29 } else {
30 self.base.fallback_decl()
31 };
32
33 let passed_ident = self
34 .ident
35 .as_ref()
36 .map(|i| quote!(#i: #input.ident.clone(),));
37 let passed_attrs = self.forward_attrs.as_initializer();
38 let passed_bounds = self
39 .bounds
40 .as_ref()
41 .map(|i| quote!(#i: #input.bounds.clone().into_iter().collect::<Vec<_>>(),));
42 let passed_default = self
43 .default
44 .as_ref()
45 .map(|i| quote!(#i: #input.default.clone(),));
46 let initializers = self.base.initializers();
47
48 let post_transform = self.base.post_transform_call();
49
50 self.wrap(
51 quote! {
52 fn from_type_param(#input: &::darling::export::syn::TypeParam) -> ::darling::Result<Self> {
53 #error_declaration
54
55 #grab_attrs
56
57 #require_fields
58
59 #error_check
60
61 #default
62
63 ::darling::export::Ok(Self {
64 #passed_ident
65 #passed_bounds
66 #passed_default
67 #passed_attrs
68 #initializers
69 }) #post_transform
70 }
71 },
72 tokens,
73 );
74 }
75}
76
77impl ExtractAttribute for FromTypeParamImpl<'_> {
78 fn attr_names(&self) -> &PathList {
79 self.attr_names
80 }
81
82 fn forward_attrs(&self) -> &ForwardAttrs<'_> {
83 &self.forward_attrs
84 }
85
86 fn param_name(&self) -> TokenStream {
87 quote!(__type_param)
88 }
89
90 fn core_loop(&self) -> TokenStream {
91 self.base.core_loop()
92 }
93
94 fn local_declarations(&self) -> TokenStream {
95 self.base.local_declarations()
96 }
97}
98
99impl<'a> OuterFromImpl<'a> for FromTypeParamImpl<'a> {
100 fn trait_path(&self) -> syn::Path {
101 path!(::darling::FromTypeParam)
102 }
103
104 fn trait_bound(&self) -> syn::Path {
105 path!(::darling::FromMeta)
106 }
107
108 fn base(&'a self) -> &'a TraitImpl<'a> {
109 &self.base
110 }
111}
112