[][src]Crate find_crate

Find the crate name from the current Cargo.toml ($crate for proc-macro).

When writing declarative macros, $crate representing the current crate is very useful, but procedural macros do not have this. If you know the current name of the crate you want to use, you can do the same thing as $crate. This crate provides the features to make it easy.

Examples

find_crate() gets the crate name from Cargo.toml.

use find_crate::find_crate;
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;

fn import() -> TokenStream {
    let name = find_crate(|s| s == "foo").unwrap();
    let name = Ident::new(&name, Span::call_site());
    // If your proc-macro crate is 2018 edition, use `quote!(use #name as _foo;)` instead.
    quote!(extern crate #name as _foo;)
}

As in this example, it is easy to handle cases where proc-macro is exported from multiple crates.

use find_crate::find_crate;
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;

fn import() -> TokenStream {
    let name = find_crate(|s| s == "foo" || s == "foo-core").unwrap();
    let name = Ident::new(&name, Span::call_site());
    // If your proc-macro crate is 2018 edition, use `quote!(use #name as _foo;)` instead.
    quote!(extern crate #name as _foo;)
}

Search for multiple crates. It is much more efficient than using find_crate() for each crate.

use find_crate::Manifest;
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;

const CRATE_NAMES: &[&[&str]] = &[
    &["foo", "foo-core"],
    &["bar", "bar-util", "bar-core"],
    &["baz"],
];

fn imports() -> TokenStream {
    let mut tts = TokenStream::new();
    let manifest = Manifest::new().unwrap();
    let manifest = manifest.lock();

    for names in CRATE_NAMES {
        let name = manifest.find_name(|s| names.iter().any(|x| s == *x)).unwrap();
        let name = Ident::new(&name, Span::call_site());
        let import_name = Ident::new(&format!("_{}", names[0]), Span::call_site());
        // If your proc-macro crate is 2018 edition, use `quote!(use #name as #import_name;)` instead.
        tts.extend(quote!(extern crate #name as #import_name;));
    }
    tts
}

By default it will be searched from dependencies, dev-dependencies and build-dependencies. Also, find_crate() and Manifest::new() read Cargo.toml in CARGO_MANIFEST_DIR as manifest.

Structs

Manifest

The manifest of cargo.

ManifestLock

A locked reference to the dependencies tables of Manifest to be searched.

Package

The package data. This has information on the current package name, original package name, and specified version.

Enums

Error

An error that occurred when getting manifest.

Constants

DEFAULT_DEPENDENCIES

The kinds of dependencies searched by default.

Functions

find_crate

Find the crate name from the current Cargo.toml.