summaryrefslogtreecommitdiff
path: root/src/codegen/from_attributes_impl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen/from_attributes_impl.rs')
-rw-r--r--src/codegen/from_attributes_impl.rs111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/codegen/from_attributes_impl.rs b/src/codegen/from_attributes_impl.rs
new file mode 100644
index 0000000..72da349
--- /dev/null
+++ b/src/codegen/from_attributes_impl.rs
@@ -0,0 +1,111 @@
+use proc_macro2::TokenStream;
+use quote::{quote, ToTokens};
+
+use crate::{
+ ast::Data,
+ codegen::{ExtractAttribute, OuterFromImpl, TraitImpl},
+ util::PathList,
+};
+
+use super::ForwardAttrs;
+
+pub struct FromAttributesImpl<'a> {
+ pub base: TraitImpl<'a>,
+ pub attr_names: &'a PathList,
+ pub forward_attrs: ForwardAttrs<'a>,
+}
+
+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<Self> {
+ ::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<Self> {
+ #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 forward_attrs(&self) -> &super::ForwardAttrs {
+ &self.forward_attrs
+ }
+
+ 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
+ }
+}