merge derive

This commit is contained in:
Robin Appelman 2023-04-02 15:51:48 +02:00
commit 461de19d2e
2 changed files with 19 additions and 23 deletions

View file

@ -12,6 +12,7 @@ syn = "2.0.12"
quote = "1.0.26" quote = "1.0.26"
proc-macro2 = "1.0.54" proc-macro2 = "1.0.54"
structmeta = "0.2.0" structmeta = "0.2.0"
merge = "0.1.0"
[dev-dependencies] [dev-dependencies]
tf-log-parser = { version = "0.1", path = ".." } tf-log-parser = { version = "0.1", path = ".." }

View file

@ -1,7 +1,9 @@
use crate::{err, Derivable, DeriveParams}; use crate::{err, Derivable, DeriveParams};
use merge::Merge;
use proc_macro2::{Ident, Span, TokenStream}; use proc_macro2::{Ident, Span, TokenStream};
use quote::{quote, quote_spanned}; use quote::{quote, quote_spanned};
use structmeta::StructMeta; use structmeta::StructMeta;
use syn::parse::Parse;
use syn::spanned::Spanned; use syn::spanned::Spanned;
use syn::{ use syn::{
Attribute, Data, DeriveInput, Field, Fields, Generics, Lifetime, LitBool, LitInt, LitStr, Attribute, Data, DeriveInput, Field, Fields, Generics, Lifetime, LitBool, LitInt, LitStr,
@ -119,7 +121,7 @@ pub struct EventParams {
impl DeriveParams for EventParams { impl DeriveParams for EventParams {
fn parse(input: &DeriveInput) -> Result<EventParams> { fn parse(input: &DeriveInput) -> Result<EventParams> {
let attrs: EventAttr = parse_attrs(&input.attrs); let attrs: StructAttrs = parse_attrs(&input.attrs);
let Data::Struct(data) = &input.data else { let Data::Struct(data) = &input.data else {
return err("only supported on structs", input); return err("only supported on structs", input);
}; };
@ -154,7 +156,7 @@ impl DeriveParams for EventParams {
.map(|lifetime| lifetime.lifetime) .map(|lifetime| lifetime.lifetime)
.unwrap_or_else(|| Lifetime::new("'_", name.span())); .unwrap_or_else(|| Lifetime::new("'_", name.span()));
if lifetimes.next().is_some() { if lifetimes.next().is_some() {
return err("For structs with more than one lifetime, manually specifiying the lifetime is required", name); return err("For structs with more than one lifetime, manually specifying the lifetime is required", name);
} }
lifetime lifetime
}; };
@ -180,7 +182,7 @@ pub struct EventParam {
impl EventParam { impl EventParam {
pub fn parse(input: &Field) -> Result<EventParam> { pub fn parse(input: &Field) -> Result<EventParam> {
let attrs: EventAttr = parse_attrs(&input.attrs); let attrs: FieldAttrs = parse_attrs(&input.attrs);
let field_name = input.ident.clone().expect("no name on named fields"); let field_name = input.ident.clone().expect("no name on named fields");
let param_name = if attrs.unnamed { let param_name = if attrs.unnamed {
None None
@ -261,37 +263,30 @@ impl EventParam {
} }
} }
fn parse_attrs(attrs: &[Attribute]) -> EventAttr { fn parse_attrs<T: Parse + Default + Merge>(attrs: &[Attribute]) -> T {
let mut result = EventAttr::default(); let mut result = T::default();
for attr in attrs { for attr in attrs {
if let Ok(parsed) = attr.parse_args() { if let Ok(parsed) = attr.parse_args() {
result = result.merge(parsed); result.merge(parsed);
} }
} }
result result
} }
#[derive(Default, StructMeta)] #[derive(Default, StructMeta, Merge)]
struct EventAttr { struct StructAttrs {
quoted: Option<LitBool>,
subject: bool,
default: bool,
unnamed: bool,
skip_after: Option<LitInt>,
name: Option<LitStr>,
lifetime: Option<Lifetime>, lifetime: Option<Lifetime>,
} }
impl EventAttr { #[derive(Default, StructMeta, Merge)]
fn merge(self, other: Self) -> Self { struct FieldAttrs {
Self { quoted: Option<LitBool>,
quoted: self.quoted.or(other.quoted), #[merge(strategy = merge::bool::overwrite_false)]
subject: self.subject || other.subject, subject: bool,
default: self.default || other.default, #[merge(strategy = merge::bool::overwrite_false)]
unnamed: self.unnamed || other.unnamed, default: bool,
skip_after: self.skip_after.or(other.skip_after), #[merge(strategy = merge::bool::overwrite_false)]
name: self.name.or(other.name), unnamed: bool,
lifetime: self.lifetime.or(other.lifetime), skip_after: Option<LitInt>,
} name: Option<LitStr>,
}
} }