William Taylor
William Taylor

Reputation: 619

Else case in conditional compile in rust

How can I have some code being compiled only when no cfg block match? For example something like this:

#IF NUM == 1
//something
#ELSE IF NUM == 2
// something
#ELSE
// no case match, panic!
#ENDIF

Upvotes: 5

Views: 5951

Answers (2)

Masklinn
Masklinn

Reputation: 42272

By hand e.g.

#[cfg(thing1)]
// something
#[cfg(all(not(thing1), thing2))]
// something
#[cfg(all(not(thing1), not(thing2)))]
// no case

Alternatively, within a function and if your "something"s are compilable in every case, you can use cfg!. Since it evaluates to a literal there's a good chance the optimiser will strip out the bits which don't match:

if cfg!(thing1) {
    // something
} else if cfg!(thing2) {
    // something
} else {
    panic!();
}

although compile_error would make more sense than panic.

There is also a cfg-if crate for something more ergonomic.

For more on the topic, see the article Yak shaving conditional compilation in Rust which expands on and discusses the various approaches.

Upvotes: 10

Michael Anderson
Michael Anderson

Reputation: 73480

You can use not in the conditional part of a cfg block. You can see an example in the docs for cfg

// This function only gets compiled if the target OS is linux
#[cfg(target_os = "linux")]
fn are_you_on_linux() {
    println!("You are running linux!");
}

// And this function only gets compiled if the target OS is *not* linux
#[cfg(not(target_os = "linux"))]
fn are_you_on_linux() {
    println!("You are *not* running linux!");
}

If you need something more complicated you can also use any and all, something like:

#[cfg(target_os="linux")]
fn get_os() -> &str { return "Linux"; }

#[cfg(target_os="windows")]
fn get_os() -> &str { return "Windows"; }

#[cfg(not(any(target_os="linux", target_os="windows")))]
fn get_os() -> &str { return "Unknown"; }

Further details are available in the reference.

Upvotes: 4

Related Questions