TedDriggs / darling

A Rust proc-macro attribute parser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow delegating attributes to `FromAttributes` types

DCNick3 opened this issue · comments

When deriving, for example, FromDeriveInput, it might be useful to delegate parsing of some (or all) attributes to a field that implements FromAttributes.

Possible use-cases

I see this feature covering two use-cases:

  1. non-standard parsing logic. This includes, for example, #246: it allows to hand-write only the FromAttributes impl, while deriving all other logic
  2. parsing different attributes using different models (see below for example)

How it can look

Adding #[darling(delegate_attrs)] on a field makes darling call FromAttributes::from_attributes to get the value.

For the use-case 2 the parsing code would look something likes this:

// define the attribute parsers

#[derive(Debug, Clone, FromAttributes)]
#[darling(attributes(schema))]
struct SchemaAttributes {
    transparent: Transparent,
}

#[derive(Debug, Clone, FromAttributes)]
#[darling(attributes(codec))]
struct CodecAttributes {
    #[darling(default)]
    skip: bool,
    #[darling(default)]
    compact: bool,
    index: Option<u8>,
}

// define the receiver struct

#[derive(Debug, Clone)]
struct IntoSchemaInput {
    ident: syn2::Ident,
    generics: syn2::Generics,
    data: IntoSchemaData,
    #[darling(delegate_attrs)]
    codec_attrs: CodecAttributes,
    #[darling(delegate_attrs)]
    schema_attrs: SchemaAttributes,
}

And it would parse this:

#[derive(IntoSchema)]
// different fields for different attributes!
#[codec(compact)]
#[schema(transparent)]
struct SchemaStruct {
  a: u32, b: i32
}

This is now supported as of 0.20.8 by allowing you to specify #[darling(with = ...)] on the attrs field. The with value is a path to a function with the signature fn(Vec<Attribute>) -> darling::Result<T> where T is the type of the attrs field in your receiver struct.