I am writing documentation for a module that has some options controlled by a Cargo feature flag. I'd like to always show this documentation so that consumers of the crate know that it's available, but I need to only run the example when the feature is enabled.
//! This crate has common utility functions
//!
//! ```
//! assert_eq!(2, featureful::add_one(1));
//! ```
//!
//! You may also want to use the feature flag `solve_halting_problem`:
//!
//! ```
//! assert!(featureful::is_p_equal_to_np());
//! ```
pub fn add_one(a: i32) -> i32 {
a + 1
}
#[cfg(feature = "solve_halting_problem")]
pub fn is_p_equal_to_np() -> bool {
true
}
[package]
name = "featureful"
version = "0.1.0"
authors = ["An Devloper <[email protected]>"]
[features]
solve_halting_problem = []
[dependencies]
Running with the feature enabled runs both doctests as expected:
$ cargo test --features=solve_halting_problem
Doc-tests featureful
running 2 tests
test src/lib.rs - (line 7) ... ok
test src/lib.rs - (line 3) ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running without the feature has an error:
$ cargo test
Doc-tests featureful
running 2 tests
test src/lib.rs - (line 7) ... FAILED
test src/lib.rs - (line 3) ... ok
failures:
---- src/lib.rs - (line 7) stdout ----
error[E0425]: cannot find function `is_p_equal_to_np` in module `featureful`
--> src/lib.rs:8:21
|
4 | assert!(featureful::is_p_equal_to_np());
| ^^^^^^^^^^^^^^^^ not found in `featureful`
Both the ```ignore
and ```no_run
modifiers apply when the feature is enabled or not, so they don't seem to be useful.
How would one achieve conditional compilation with Rust projects that have doctests? is close, but the answer focuses on functions that change with conditional compilation, not on documentation of modules.
This works, too, and I think is much cleaner:
//! This crate has common utility functions
//!
//! ```
//! assert_eq!(2, featureful::add_one(1));
//! ```
//!
#![cfg_attr(
not(feature = "solve_halting_problem"),
doc = "You may also want to use the feature flag `solve_halting_problem`:"
)]
#![cfg_attr(
feature = "solve_halting_problem",
doc = "This example works because the `solve_halting_problem` feature flag is enabled:"
)]
//!
#![cfg_attr(not(feature = "solve_halting_problem"), doc = "```ignore")]
#![cfg_attr(feature = "solve_halting_problem", doc = "```")]
//! assert!(featureful::is_p_equal_to_np());
//! ```
I only see one solution: put the #[cfg]
inside the test:
//! ```
//! #[cfg(feature = "solve_halting_problem")]
//! assert!(featureful::is_p_equal_to_np());
//! ```
This will count as a test but it will be empty when the feature is not enabled. You can pair this with the ability to hide portions of the example and the fact that you can put the #[cfg]
attribute on entire blocks as well:
//! ```
//! # #[cfg(feature = "solve_halting_problem")] {
//! assert!(featureful::is_p_equal_to_np());
//! // Better double check
//! assert!(featureful::is_p_equal_to_np());
//! # }
//! ```
As a note, maybe you could use #![feature(doc_cfg)]
like this:
/// This function is super useful
///
/// ```
/// assert!(featureful::is_p_equal_to_np());
/// ```
#[cfg(any(feature = "solve_halting_problem", feature = "dox"))]
#[doc(cfg(feature = "solve_halting_problem"))]
pub fn is_p_equal_to_np() -> bool {
true
}
This will not run the test when the feature is disabled but this will generate the doc with cargo doc --features dox
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With