user1363145
user1363145

Reputation: 127

How can I extract a type from a procedural macro attribute using darling?

I need to be able to extract the type DieselHandler, ideally in a way that allows for repeatable data_loader attributes for transforming against multiple types.

#[derive(Loadable)]
#[data_loader(handler = DieselHandler<FooLoader>)]

If I use handler: syn::Type there is the error:

the trait bound syn::Type: FromMeta is not satisfied the trait FromMeta is not implemented for syn::Type

How can I pass in a type here and maybe even check the wrapper structure?

#[derive(Debug, FromDeriveInput)]
#[darling(attributes(data_loader))]
struct LoadByArgs {
  #[darling(default)]
  internal: bool,
  handler: ????,
}

#[proc_macro_derive(Loadable, attributes(data_loader))]
pub fn load_by(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
  let input = parse_macro_input!(input as DeriveInput);

  let LoadByArgs {
    internal, handler
  } = FromDeriveInput::from_derive_input(&input).expect("can't parse attribute");

  let expanded = quote! {
      ...
  };

  proc_macro::TokenStream::from(expanded)
}

Upvotes: 2

Views: 1047

Answers (1)

ehdv
ehdv

Reputation: 4603

darling requires the quotation marks when writing #[attr(foo = "bar")] because syn doesn't consider the quotation-free form to be a valid Meta, and the Meta is the basis of darling's entire API.

That's consistent with serde, which I still view as the closest thing to a standard for proc-macro APIs in Rust.

You can use darling::util::PathList if you want to write something like #[data_loader(DieselHandler)]. Technically type parameters are part of a path, so DieselHandler<FooLoader> should work on paper.

Upvotes: 1

Related Questions