-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This allows the `attrs` magic field to have any type, rather than being limited to `Vec<Attribute>`. Fixes #273
- Loading branch information
Showing
16 changed files
with
273 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
use quote::{quote, quote_spanned, ToTokens, TokenStreamExt}; | ||
use syn::spanned::Spanned; | ||
|
||
use crate::options::AttrsField; | ||
|
||
pub struct Declaration<'a>(pub &'a AttrsField); | ||
|
||
impl ToTokens for Declaration<'_> { | ||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { | ||
let ident = &self.0.ident; | ||
tokens.append_all(quote! { | ||
let mut __fwd_attrs: ::darling::export::Vec<::darling::export::syn::Attribute> = vec![]; | ||
let mut #ident: ::darling::export::Option<_> = None; | ||
}); | ||
} | ||
} | ||
|
||
pub struct ValuePopulator<'a>(pub &'a AttrsField); | ||
|
||
impl ToTokens for ValuePopulator<'_> { | ||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { | ||
let AttrsField { ident, with } = self.0; | ||
let initializer_expr = match with { | ||
Some(with) => quote_spanned!(with.span()=> __errors.handle(#with(__fwd_attrs))), | ||
None => quote!(::darling::export::Some(__fwd_attrs)), | ||
}; | ||
tokens.append_all(quote!(#ident = #initializer_expr;)); | ||
} | ||
} | ||
|
||
pub struct Initializer<'a>(pub &'a AttrsField); | ||
|
||
impl ToTokens for Initializer<'_> { | ||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { | ||
let ident = &self.0.ident; | ||
tokens.append_all(quote!(#ident: #ident.expect("Errors were already checked"),)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
mod attr_extractor; | ||
pub(in crate::codegen) mod attrs_field; | ||
mod default_expr; | ||
mod error; | ||
mod field; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use proc_macro2::Ident; | ||
use syn::Path; | ||
|
||
use crate::{Error, FromField, FromMeta}; | ||
|
||
use super::ParseAttribute; | ||
|
||
/// The `attrs` magic field and attributes that influence its behavior. | ||
#[derive(Debug, Clone)] | ||
pub struct AttrsField { | ||
/// The ident of the field that will receive the forwarded attributes. | ||
pub ident: Ident, | ||
/// Path of the function that will be called to convert the `Vec` of | ||
/// forwarded attributes into the type expected by the field in `ident`. | ||
pub with: Option<Path>, | ||
} | ||
|
||
impl FromField for AttrsField { | ||
fn from_field(field: &syn::Field) -> crate::Result<Self> { | ||
let result = Self { | ||
ident: field.ident.clone().ok_or_else(|| { | ||
Error::custom("attributes receiver must be named field").with_span(field) | ||
})?, | ||
with: None, | ||
}; | ||
|
||
result.parse_attributes(&field.attrs) | ||
} | ||
} | ||
|
||
impl ParseAttribute for AttrsField { | ||
fn parse_nested(&mut self, mi: &syn::Meta) -> crate::Result<()> { | ||
if mi.path().is_ident("with") { | ||
if self.with.is_some() { | ||
return Err(Error::duplicate_field_path(mi.path()).with_span(mi)); | ||
} | ||
|
||
self.with = FromMeta::from_meta(mi)?; | ||
Ok(()) | ||
} else { | ||
Err(Error::unknown_field_path_with_alts(mi.path(), &["with"]).with_span(mi)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.