我的箱子如何检查依赖项的选定功能?

Max*_*axV 5 rust rust-cargo

我正在寻找一种基于依赖项的功能选择提供特殊功能的方法。

有一个crate-a具有功能feature-afeature-b. 我想创建一个crate-b依赖于crate-a.

二进制crate-c取决于crate-acrate-b并指定 的功能crate-a

我想根据为 选择的功能集提供crate-b的功能的不同实现。greetcrate-a

我试过这种不起作用的方法:

// at crate-b/src/lib.rs

#[cfg(not(feature = "crate-a/feature-a"))]
pub fn greet() {
    println!("General impl");
}

#[cfg(feature = "crate-a/feature-a")]
pub fn greet() {
    println!("Feature-A impl");
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以检查crate-a的功能crate-b吗?

我控制crate-acrate-b。即使是一种应该改变某些东西的方法crate-a对我来说也是有效的。

ape*_*lla 5

我能想到的在编译时实现此目的的唯一方法是crate-a根据启用的功能有条件地定义宏。例如,专门feature-a指定何时的宏如下所示:

// in crate-a/src/lib.rs
#[cfg(feature = "feature-a")]
#[doc(hidden)]
#[macro_export]
macro_rules! __cfg_feature_a {
    ( $( $tok:tt )* ) => { $( $tok )* }
}

#[cfg(not(feature = "feature-a"))]
#[doc(hidden)]
#[macro_export]
macro_rules! __cfg_feature_a {
    ( $( $tok:tt )* ) => {}
}
Run Code Online (Sandbox Code Playgroud)

这些宏可供其他 crate 使用,但从crate-avia的公共 API 中隐藏#[doc(hidden)],并且根据功能标志,它们扩展为与给定的相同标记或空主体。然后您可以像这样使用它们crate-b

// in crate-b/src/lib.rs
pub fn unconditional_fn() {}

crate_a::__cfg_feature_a! {
    pub fn cfg_feature_a_fn() {}
}
Run Code Online (Sandbox Code Playgroud)

这显然是一个相当老套的解决方案,并且需要为您使用的每个功能标志组合定义大量的样板宏,但应该适用于基于crate-a.

编辑:作为参考,在 1.0.187 版本之前,serde对其宏使用了类似的方法。serde_if_integer128