1 unstable release
0.0.1 | Jun 20, 2024 |
---|
#16 in #exclusive
8KB
61 lines
cfg-feature
A procedural macro for ensuring that only one of a set of features is enabled at a time.
Typically, features should be additive. However, there are times when this is not possible or desired.
For such cases, if the number of features is small, or does not change/evolve frequently some verbose #[cfg]
attributes may suffice.
The Problem
For example imagine a fictional crate which should only be build with one
of the features feat1
or feat2
.
One could create a build script such as the one at build.rs
.
fn main() {
#[cfg(all(feature = "feat1", feature = "feat2"))]
compile_error!("Only one of the features can be enabled at a time");
}
Now imagine, we add a feat3
.
Our build.rs
changes to:
fn main() {
#[cfg(any(
all(feature = "feat1", any(feature = "feat2", feature = "feat3")),
all(feature = "feat2", any(feature = "feat1", feature = "feat3")),
all(feature = "feat3", any(feature = "feat1", feature = "feat2")),
))]
compile_error!("Only one of the features can be enabled at a time");
}
Adding a fourth feat4
jumps to 12 combinations!
fn main() {
#[cfg(any(
all(feature = "feat1", any(feature = "feat2", feature = "feat3", feature = "feat4")),
all(feature = "feat2", any(feature = "feat1", feature = "feat3", feature = "feat4")),
all(feature = "feat3", any(feature = "feat1", feature = "feat2", feature = "feat4")),
all(feature = "feat4", any(feature = "feat1", feature = "feat2", feature = "feat3")),
))]
compile_error!("Only one of the features can be enabled at a time");
}
This gets out of hand quickly.
The Solution
Starting of with two features, the cfg-exclusive
procedural macro can be used to simplify the build.rs
script.
cfg_exclusive::cfg_exclusive! {
validate_feats,
["feat1", "feat2"],
"Only one of the features can be enabled at a time"
}
fn main() {
validate_feats();
}
If that changes to three features:
- ["feat1", "feat2"],
+ ["feat1", "feat2", "feat3"],
Or four:
- ["feat1", "feat2", "feat3"],
+ ["feat1", "feat2", "feat3", "feat4"],
License
This crate is licensed under either of
at your option.
Contribution
Unless you explicitly note otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~240–690KB
~16K SLoC