Skip to main content

darling_core/codegen/
from_type_param.rs

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}