Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kbknapp/cfg-exclusive
A procedural macro for handling mutually-exclusive crate features
https://github.com/kbknapp/cfg-exclusive
Last synced: 25 days ago
JSON representation
A procedural macro for handling mutually-exclusive crate features
- Host: GitHub
- URL: https://github.com/kbknapp/cfg-exclusive
- Owner: kbknapp
- License: apache-2.0
- Created: 2024-06-20T20:31:32.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2024-06-20T20:42:25.000Z (5 months ago)
- Last Synced: 2024-10-05T14:15:11.935Z (about 1 month ago)
- Language: Rust
- Size: 9.77 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# `cfg-exclusive`
![Rust Version][rustc-image]
[![crates.io][crate-image]][crate-link]
[![Documentation][docs-image]][docs-link]
[![Dependency Status][deps-image]][deps-link]A procedural macro for ensuring that only one of a set of features is enabled at a time.
* [The Problem](#the-problem)
* [The Solution](#the-solution)
* [License](#license)
* [Contribution](#contribution)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`.
```rust
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:
```rust
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!
```rust
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.
```rust
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:
```diff
- ["feat1", "feat2"],
+ ["feat1", "feat2", "feat3"],
```Or four:
```diff
- ["feat1", "feat2", "feat3"],
+ ["feat1", "feat2", "feat3", "feat4"],
```## License
This crate is licensed under either of
* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
* [MIT license](http://opensource.org/licenses/MIT)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.[//]: # (badges)
[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg
[crate-image]: https://img.shields.io/crates/v/cfg-exclusive.svg
[crate-link]: https://crates.io/crates/cfg-exclusive
[docs-image]: https://docs.rs/cfg-exclusive/badge.svg
[docs-link]: https://docs.rs/cfg-exclusive
[deps-image]: https://deps.rs/repo/github/kbknapp/cfg-exclusive/status.svg
[deps-link]: https://deps.rs/repo/github/kbknapp/cfg-exclusive[//]: # (links)