dtolnay / inventory

Typed distributed plugin registration
Apache License 2.0
986 stars 43 forks source link

Document extern usage #33

Closed Bajix closed 2 years ago

Bajix commented 3 years ago

Currently any library that exports macros that use inventory for submitting plugins cannot rely on pub extern crate inventory as a means to re-export and as such inventory always has to be added to the end consumer as a dependency. Ideally this could be done without asking end consumers to add inventory as a dependency.

jerel commented 3 years ago

I just ran into this as well and while reading the inventory source found that this is supported via an attribute. This is how my [working] project is now configured:

// acme_macro/src/lib.rs
#[proc_macro_attribute]
pub fn my_macro(_attrs: TokenStream, input: TokenStream) -> TokenStream {
  let out = quote! {
    ::acme::inventory::submit! {
      #![crate = ::acme]
      // additional plugin code goes here
    }
  }

  // other macro work
}

// acme/src/lib.rs
pub use inventory;
pub use acme_macro::my_macro;

// some_crate/src/bin.rs
use acme::my_macro;
Bajix commented 3 years ago

So it's the '#![crate = ::acme]' attribute that makes this work? I guess the generated output would still have inventory but it'll resolve differently? That's a really clever workaround

jerel commented 3 years ago

@Bajix thats's correct, the crate is parsed here from an outer attribute and is used here in the path as macro variable #prefix in the #prefix inventory::submit({ #expr }); statement (Rust allows spaces in paths so the gap after prefix is fine).

Bajix commented 3 years ago

Very nifty. I released an updated version of booter using this technique so that it no longer requires the consumer to add inventory. As far as I can tell though this isn't documented and I think it would be a very helpful note for other would-be integrators.

dtolnay commented 2 years ago

This is no longer applicable as of inventory 0.2.