我正在尝试重新导出第三方板条箱,以便我的库的消费者不必手动添加通过 proc 宏生成的某些代码所需的所有依赖项。
但是,我似乎无法获得编译器要解析的路径,即使我获得了导航到该路径的代码完成。
如何从我自己的包中正确地重新导出第三方包,以便使用我的 proc 宏的包的消费者不必手动添加第三方包来支持生成的代码?
下面是一个简化的示例,它应该与我的问题等同,即使我的真实项目在由我自己的 proc 宏生成的代码中解析此路径时存在问题。
文件结构:
│ Cargo.lock
│ Cargo.toml
│ rust-toolchain.toml
│
├───consumer
│ │ .gitignore
│ │ Cargo.toml
│ │
│ └───src
│ main.rs
│
└───exporter
│ .gitignore
│ Cargo.toml
│
└───src
lib.rs
在我的“消费者”板条箱中,我尝试使用板条箱Debug
提供的派生宏derive_more
。
消费者中的 Main.rs:
#[derive(exporter::reexports::derive_more::Debug)]
pub struct Foo {
x: u64
}
fn main() {
println!("Hello, world!");
}
消费者中的 Cargo.toml:
[package]
name = "consumer"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
exporter = { path = "../exporter" }
导出器中的 lib.rs:
pub mod reexports {
pub use derive_more;
}
出口商中的 Cargo.toml:
[package]
name = "exporter"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
derive_more = { version = "2", features = ["full"] }
这里的错误本身并不是重新导出的问题——编译器能够找到并运行 derive-more
Debug
宏,问题在于该宏生成的输出。派生宏
Debug
将生成以下内容:如您所见,它发出的代码预期
derive_more
会在作用域内,因为它依赖于自身的重新导出。不幸的是,在您的情况下,由于消费者 crate 不直接依赖于 derive-more,因此它不会像通常那样自动在作用域内。解决方案是
derive_more
通过重新导出将其纳入范围:一些像 serde 这样的板条箱允许您指定要使用的不同路径
serde
(如#[serde(crate = "exporter::reexports::serde")]
),但并非所有板条箱都这样做,这只是解决上述问题的另一种方法。不幸的是,过程宏就是这样工作的。如何为过程宏提供一种避免这个问题的方法,是一个悬而未决的问题(注意,它们可以明确地引用自身,但不能引用它们所附带的非过程宏 crate)。