macro_rules! cfg_block { ( $( if #[cfg($meta:meta)] { $($item:item)* } else { $($item_f:item)* } )* ) => { ... }; ( $( #[$meta:meta] { $( $item:item )* } )* ) => { ... }; }
Expand description
Allow applying inner procedural macros to a {}
block, which helps a lot
with platform-based const
values.
§Examples
Basic example handling differnt
use cfg_block::cfg_block;
cfg_block! {
#[cfg(target_family = "unix")] {
const PLATFORM: &str = "posix !";
const MY_NUMBER: u8 = 5;
}
#[cfg(target_family = "windows")] {
const PLATFORM: &str = "windows !";
const MY_NUMBER: u16 = 20;
}
#[cfg(target_family = "wasm")] {
const PLATFORM: &str = "web !";
const MY_NUMBER: i32 = -5;
}
}
// This is a proof of concept
match PLATFORM {
"posix !" => assert_eq!(MY_NUMBER as i32, 5),
"windows !" => assert_eq!(MY_NUMBER as i32, 20),
"web !" => assert_eq!(MY_NUMBER as i32, -5),
&_ => panic!(),
}
Or, with the if/else syntax (only works for cfg
macros):
use cfg_block::cfg_block;
cfg_block! {
if #[cfg(mips)] {
const STR_A: &str = "where did you get this processor";
const STR_B: &str = "mips just makes a good passing doctest";
} else {
const STR_A: &str = "good!";
const STR_B: &str = "better!";
}
}
assert_eq!(STR_A, "good!");
assert_eq!(STR_B, "better!");
Currently, if/else statements need to be in a separate cfg_block! {}
from
options that do not use if/else.
It is also possible to put anything that rust considers an item
inside the
block. Note that this does not include let
bindings.
use cfg_block::cfg_block;
cfg_block! {
if #[cfg(mips)] {
const STR_A: &str = "where did you get this processor";
} else {
const STR_A: &str = "good!";
}
if #[cfg(not(mips))] {
assert_eq!(STR_A, "good!");
} else {}
}