Providing support for $crate
in procedural macros.
In macro_rules!
$crate
is used to get the path of the crate where a macro is declared in. In
procedural macros there is currently no easy way to get this path. A common hack is to import the
desired crate with a know name and use this. However, with rust edition 2018 and dropping
extern crate
declarations from lib.rs
, people start to rename crates in Cargo.toml
directly.
However, this breaks importing the crate, as the proc-macro developer does not know the renamed
name of the crate that should be imported.
This crate provides a way to get the name of a crate, even if it renamed in Cargo.toml
. For this
purpose a single function crate_name
is provided. This function needs to be called in the context
of a proc-macro with the name of the desired crate. CARGO_MANIFEST_DIR
will be used to find the
current active Cargo.toml
and this Cargo.toml
is searched for the desired crate.
use quote::quote;
use syn::Ident;
use proc_macro2::Span;
use proc_macro_crate::{crate_name, FoundCrate};
fn import_my_crate() {
let found_crate = crate_name("my-crate").expect("my-crate is present in `Cargo.toml`");
match found_crate {
FoundCrate::Itself => quote!( crate::Something ),
FoundCrate::Name(name) => {
let ident = Ident::new(&name, Span::call_site());
quote!( #ident::Something )
}
};
}
There are multiple edge cases when it comes to determining the correct crate. If you for example import a crate as its own dependency, like this:
[package]
name = "my_crate"
[dev-dependencies]
my_crate = { version = "0.1", features = [ "test-feature" ] }
The crate will return FoundCrate::Itself
and you will not be able to find the other instance
of your crate in dev-dependencies
. Other similar cases are when one crate is imported multiple
times:
[package]
name = "my_crate"
[dependencies]
some-crate = { version = "0.5" }
some-crate-old = { package = "some-crate", version = "0.1" }
When searching for some-crate
in this Cargo.toml
it will return FoundCrate::Name("some_old_crate")
,
aka the last definition of the crate in the Cargo.toml
.
Licensed under either of
at your option.
crate_name
.orig_name
in the current Cargo.toml
.