I have a function and a test for it. I want the function to return additional information to be printed in case the test fails. Collecting this information is performance heavy and I want it only for this particular test. That means that I do not want to enable it always when test configuration is enabled.
I invented something like this, but I do not like this debug_info parameter that I have to pass even outside tests. Also, I do not like the if let Some(debug_info) = debug_info line: I would like my debug lines to be as small as possible.
fn foo(debug_info: Option<&mut String>) -> bool {
if cfg!(test) {
if let Some(debug_info) = debug_info {
*debug_info += "some debug stuff";
}
}
false
}
fn main() {
// normal operation
foo(None);
// test debug_info not used if not in tests
let mut debug_info = String::new();
foo(Some(&mut debug_info));
assert_eq!(debug_info, ""); // debug_info ignored
}
#[cfg(test)]
mod tests {
use crate::foo;
#[test]
fn test() {
let mut debug_info = String::new();
assert!(
foo(Some(&mut debug_info)),
"failed with info: {}",
debug_info
);
}
}
The reference does mention it briefly here but it only shows examples on the item level. The fact that you can use it on expressions is only implied by the line at the end
The cfg attribute is allowed anywhere attributes are allowed.
Yeah there's a good chance it does get eliminated in a later pass, but not compiling it at all can help compilation times if you have big complicated expressions that need to be type checked, for example.
In this case it probably wouldn't make a meaningful difference though, just wanted to point out that it was possible!