我的箱子如何检查依存关系的选定功能?

问题描述

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

一个int set(string key,string value) { // Use existing element from map if it exists,// or create a new if it doesn't container[key].push_back(value); // The vector is guaranteed to exist at this point,// and contain at least one element return container[key].size() - 1; } ,具有功能crate-afeature-a。我想创建一个依赖于feature-b的新库crate-b

二进制crate-a同时取决于crate-ccrate-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-bcrate-a。甚至应该在crate-b中进行某些更改的方法也对我有效。

解决方法

我能想到的唯一在编译时实现此目标的方法是根据启用的功能在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使用类似于其serde_if_integer128宏的方法。