Closed Bajix closed 2 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;
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
@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).
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.
This is no longer applicable as of inventory 0.2.
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.