use proc_macro2::TokenStream; use quote::{quote, ToTokens}; use crate::{ ast::Data, codegen::{ExtractAttribute, OuterFromImpl, TraitImpl}, options::ForwardAttrs, util::PathList, }; pub struct FromAttributesImpl<'a> { pub base: TraitImpl<'a>, pub attr_names: &'a PathList, } impl ToTokens for FromAttributesImpl<'_> { fn to_tokens(&self, tokens: &mut TokenStream) { let ty_ident = self.base.ident; let input = self.param_name(); let post_transform = self.base.post_transform_call(); if let Data::Struct(ref data) = self.base.data { if data.is_newtype() { self.wrap( quote! { fn from_attributes(#input: &[::darling::export::syn::Attribute]) -> ::darling::Result { ::darling::export::Ok( #ty_ident(::darling::FromAttributes::from_attributes(#input)?) ) #post_transform } }, tokens, ); return; } } let inits = self.base.initializers(); let default = self.base.fallback_decl(); let grab_attrs = self.extractor(); let declare_errors = self.base.declare_errors(); let require_fields = self.base.require_fields(); let check_errors = self.base.check_errors(); self.wrap( quote! { fn from_attributes(#input: &[::darling::export::syn::Attribute]) -> ::darling::Result { #declare_errors #grab_attrs #require_fields #check_errors #default ::darling::export::Ok(#ty_ident { #inits }) #post_transform } }, tokens, ); } } impl<'a> ExtractAttribute for FromAttributesImpl<'a> { fn local_declarations(&self) -> TokenStream { self.base.local_declarations() } fn attr_names(&self) -> &PathList { self.attr_names } fn forwarded_attrs(&self) -> Option<&ForwardAttrs> { None } fn param_name(&self) -> TokenStream { quote!(__di) } fn attrs_accessor(&self) -> TokenStream { self.param_name() } fn core_loop(&self) -> TokenStream { self.base.core_loop() } } impl<'a> OuterFromImpl<'a> for FromAttributesImpl<'a> { fn trait_path(&self) -> syn::Path { path!(::darling::FromAttributes) } fn trait_bound(&self) -> syn::Path { path!(::darling::FromMeta) } fn base(&'a self) -> &'a TraitImpl<'a> { &self.base } }