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