我正在寻找一种基于依赖项的功能选择来提供特殊功能的方法。
有一个库
crate-a
,具有 feature-a
和 feature-b
功能。我想创建一个新的库 crate-b
,它依赖于 crate-a
。
二进制
crate-c
取决于 crate-a
和 crate-b
并指定 crate-a
的特征。
我想根据为
crate-b
选择的功能集提供 greet
功能 crate-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");
}
有没有办法从
crate-a
查看crate-b
的功能?
我同时控制
crate-a
和crate-b
。即使是应该在 crate-a
中进行更改的方法也适合我。
我能想到的在编译时实现此目的的唯一方法是根据启用的功能有条件地在
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 )* ) => {}
}
这些宏可供其他板条箱使用,但通过
crate-a
对 #[doc(hidden)]
的公共 API 隐藏,并且根据功能标志,它们会扩展为与给定的相同标记或空主体。然后您可以在 crate-b
中使用它们,如下所示:
// in crate-b/src/lib.rs
pub fn unconditional_fn() {}
crate_a::__cfg_feature_a! {
pub fn cfg_feature_a_fn() {}
}
这显然是一个相当老套的解决方案,并且需要为您使用的每个功能标志组合定义大量的样板宏,但应该适用于基于
crate-a
功能的编译时条件编译。
编辑:仅供参考,
serde
在 1.0.187 版之前使用了类似的方法及其 serde_if_integer128
宏。