cfg-exclusive

Crates.iocfg-exclusive
lib.rscfg-exclusive
version0.0.1
sourcesrc
created_at2024-06-20 20:41:23.947342
updated_at2024-06-20 20:41:23.947342
descriptionA procedural macro for defining mutually exclusive cfg attributes.
homepage
repositoryhttps://github.com/kbknapp/cfg-exclusive
max_upload_size
id1278519
size19,891
Kevin K. (kbknapp)

documentation

https://docs.rs/cfg-exclusive/

README

cfg-feature

Rust Version crates.io Documentation Dependency Status

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.

Commit count: 3

cargo fmt