rust 我的crate如何检查依赖项的选定特性?

4sup72z8  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(109)

我正在寻找一种方法来提供基于依赖项的特性选择的特殊功能。
有一个库crate-a具有feature-afeature-b的功能。我想创建一个新的库crate-b,它依赖于crate-a
二进制crate-c依赖于crate-acrate-b,并指定crate-a的功能。
我想根据为crate-a选择的特性集提供crate-b的函数greet的不同实现。
我试过这种方法,但不起作用:

// 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-b检查crate-a的功能吗?
我同时控制crate-acrate-b。即使是在crate-a中需要更改的方法也适用于我。

8ehkhllq

8ehkhllq1#

我能想到的在编译时实现这一点的唯一方法是根据启用的功能在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使用,但是通过#[doc(hidden)]crate-a的公共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宏中使用了类似的方法,直到版本1.0.187。

相关问题