如何在 Rust 中设置宏的依赖关系?

ska*_*ori 7 rust

我在板条箱中编写了一个宏,并将其导入主项目的主函数中。

宏取决于:

use chrono::{Utc, Local, DateTime, Date};
Run Code Online (Sandbox Code Playgroud)

目前我将依赖项包含在主项目的 Cargo.toml 中。

我需要对所有主要项目做同样的事情吗?或者我可以在宏包的 Cargo.toml 中声明依赖项吗?

//lib.rs //Mymacro 
#[macro_export]
macro_rules! time {
    () => {
        use chrono::{Utc, Local, DateTime, Date};
        let local_datetime: DateTime<Local> = Local::now();
        println!("{:?}",local_datetime);
    }
}
Run Code Online (Sandbox Code Playgroud)
//main.rs // main project
extern crate Mymacro;

#[macro_use]
fn main() {
    time!();
}

// Cargo.toml
[dependencies] 
chrono=""
Run Code Online (Sandbox Code Playgroud)

Val*_*tin 9

我需要对所有主要项目做同样的事情吗?或者我可以在宏包的 Cargo.toml 中声明依赖项吗?

您可以通过 (1) 让宏调用库中的函数或 (2) 重新导出chrono(部分或全部)。


让我们假设我们有一个工作区,里面有一个lib箱子bin

[workspace]
members = [
    "bin",
    "lib",
]
Run Code Online (Sandbox Code Playgroud)

现在,在您的板条Cargo.toml箱中lib,您将chrono作为依赖项包含在内,就像其他情况一样。

[dependencies]
chrono = "0.4"
Run Code Online (Sandbox Code Playgroud)

Cargo.tomlfor the bincrate 仅具有 的依赖性lib

[dependencies]
lib = { path = "../lib" }
Run Code Online (Sandbox Code Playgroud)

现在,让我们考虑一下板条箱main.rs中的bin情况:

[workspace]
members = [
    "bin",
    "lib",
]
Run Code Online (Sandbox Code Playgroud)

无论您选择哪种选项,它都将保持不变。


以下片段代表lib.rs.


库函数

如果您实际上从未返回任何chrono特定类型,那么这可能是最简单的。当您完全避免重新导出 chrono 时。

[dependencies]
chrono = "0.4"
Run Code Online (Sandbox Code Playgroud)

如果您不想_time出现在库的文档中,则可以使用该#[doc(hidden)]属性。

重新出口一些物品

或者,如果您希望所有内容都保留在宏中,那么您可以重新导出chrono它使用的类型,并在宏中的类型前面加上$crate::.

这样做的缺点是,如果您的bin板条箱需要一种chrono不重新导出的类型,那么这可能会成为“烦恼”,因此无论如何都bin需要依赖chrono = "0.4"

[dependencies]
lib = { path = "../lib" }
Run Code Online (Sandbox Code Playgroud)

如果main.rs您这样做use lib::*;,那么您当然不需要前置$crate::,但最好避免这样做use lib::*;

再出口 Chrono

最后,如果您需要板条箱chrono中的类型bin。然后您还可以使用 重新导出整个chrono箱子pub extern crate chrono;

请注意,这一次,您需要在宏中的类型前面添加$crate::chrono::.

use lib::time;

fn main() {
    time!();
}
Run Code Online (Sandbox Code Playgroud)