1

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)
}
user1363145
  • 107
  • 1
  • 2
  • 6
  • 1
    I haven't had much success with this without expressing the types as strings. ie `#[data_loader(handler = "DieselHandler")]`. `handler` can then be a `syn::Path` in your code. – Peter Hall Jul 30 '21 at 09:50
  • I think it's because darling hasn't been updated for a while, and this used to be a syntactic restriction. – Peter Hall Jul 30 '21 at 09:51
  • I was hoping to do this without the quotes and ideally with a syntax like `#[data_loader(DieselHandler)]`. Do you know of a darling alternative that would help here? I've never attempted to write a procedural macro before so I'm still picking things up – user1363145 Jul 30 '21 at 10:22
  • No I haven't seen anything. But darling really does make life a lot easier when you have attributes. It has saved me 100s of lines of very messy code. – Peter Hall Jul 30 '21 at 10:33
  • Yes I definitely see the value and really don't want to write any of that by hand. Hopefully darling will add in support or maybe examples if already possible – user1363145 Jul 30 '21 at 10:43
  • Using syn::Path unblocked me.https://github.com/Bajix/deque-loader-rs/commit/b533ab35897fd48ed3ad7ab35c93e9f7dfc2adde – user1363145 Jul 30 '21 at 11:20

1 Answers1

1

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.

ehdv
  • 4,483
  • 7
  • 32
  • 47