Macro define_alias

Source
macro_rules! define_alias {
    (
        #[cfg($meta:meta)] => $p:ident
        $(, $( $rest:tt )+)?
    ) => { ... };
    (
        #[cfg($meta:meta)] => $p:ident,
        $($( $rest:tt )+)?
    ) => { ... };
    (
        #[cfg($meta:meta)] => {
            $(#[$p_meta:meta])*
            $p:ident
        }
        $($( $rest:tt )+)?
    ) => { ... };
}
Expand description

Defines an alias for a particular configuration. This has two advantages over directly using #[cfg(...)]:

  1. Complex configurations can be abbreviated to more meaningful shorthand.
  2. Features are evaluated in the context of the defining crate, not the consuming.

The second advantage is a particularly powerful tool, as it allows consuming crates to use functionality in a defining crate regardless of what crate in the dependency graph enabled the relevant feature.

For example, consider a crate foo that depends on another crate bar. bar has a feature “faster_algorithms”. If bar defines a “faster_algorithms” alias:

define_alias! {
    #[cfg(feature = "faster_algorithms")] => { faster_algorithms }
}

Now, foo can gate its usage of those faster algorithms on the alias, avoiding the need to expose its own “faster_algorithms” feature. This also avoids the unfortunate situation where one crate activates “faster_algorithms” on bar without activating that same feature on foo.

Once an alias is defined, there are 4 ways you can use it:

  1. Evaluate with no contents to return a bool indicating if the alias is active.
    if cfg::std!() {
        // Have `std`!
    } else {
        // No `std`...
    }
  2. Pass a single code block which will only be compiled if the alias is active.
    cfg::std! {
        // Have `std`!
    }
  3. Pass a single if { ... } else { ... } expression to conditionally compile either the first or the second code block.
    cfg::std! {
        if {
            // Have `std`!
        } else {
            // No `std`...
        }
    }
  4. Use in a switch arm for more complex conditional compilation.
    cfg::switch! {
        cfg::std => {
            // Have `std`!
        }
        cfg::alloc => {
            // No `std`, but do have `alloc`!
        }
        _ => {
            // No `std` or `alloc`...
        }
    }