macro_rules! backends {
(
#[vulkan] let $vk_field:pat = $vk_expr:expr;
#[metal] let $mtl_field:pat = $mtl_expr:expr;
#[dx12] let $dx12_field:pat = $dx12_expr:expr;
#[dx11] let $dx11_field:pat = $dx11_expr:expr;
) => {
#[cfg(any(
windows,
all(unix, not(any(target_os = "ios", target_os = "macos"))),
feature = "gfx-backend-vulkan",
))]
let $vk_field = $vk_expr;
#[cfg(any(target_os = "ios", target_os = "macos"))]
let $mtl_field = $mtl_expr;
#[cfg(windows)]
let $dx12_field = $dx12_expr;
#[cfg(windows)]
let $dx11_field = $dx11_expr;
};
(
#[vulkan] $vk_block:block
#[metal] $mtl_block:block
#[dx12] $dx12_block:block
#[dx11] $dx11_block:block
) => {
#[cfg(any(
windows,
all(unix, not(any(target_os = "ios", target_os = "macos"))),
feature = "gfx-backend-vulkan",
))]
$vk_block
#[cfg(any(target_os = "ios", target_os = "macos"))]
$mtl_block
#[cfg(windows)]
$dx12_block
#[cfg(windows)]
$dx11_block
};
(
$Struct:path {
#[vulkan] $vk_field:ident: $vk_expr:expr,
#[metal] $mtl_field:ident: $mtl_expr:expr,
#[dx12] $dx12_field:ident: $dx12_expr:expr,
#[dx11] $dx11_field:ident: $dx11_expr:expr,
}
) => {{
$Struct {
#[cfg(any(
windows,
all(unix, not(any(target_os = "ios", target_os = "macos"))),
feature = "gfx-backend-vulkan",
))]
$vk_field: $vk_expr,
#[cfg(any(target_os = "ios", target_os = "macos"))]
$mtl_field: $mtl_expr,
#[cfg(windows)]
$dx12_field: $dx12_expr,
#[cfg(windows)]
$dx11_field: $dx11_expr,
}
}};
}
macro_rules! backends_map {
(
let map = |$backend:pat| $map:block;
$(
#[$backend_attr:ident] let $pat:pat = map($expr:expr);
)*
) => {
backends! {
$(
#[$backend_attr]
let $pat = {
let $backend = $expr;
$map
};
)*
}
};
(
let map = |$backend:pat| $map:block;
$(
#[$backend_attr:ident] map($expr:expr),
)*
) => {
backends! {
$(
#[$backend_attr]
{
let $backend = $expr;
$map
}
)*
}
};
(
let map = |$backend:pat| $map:block;
$Struct:path {
$(
#[$backend_attr:ident] $ident:ident : map($expr:expr),
)*
}
) => {
backends! {
$Struct {
$(
#[$backend_attr]
$ident: {
let $backend = $expr;
$map
},
)*
}
}
};
}
#[test]
fn test_backend_macro() {
struct Foo {
#[cfg(any(
windows,
all(unix, not(any(target_os = "ios", target_os = "macos"))),
feature = "gfx-backend-vulkan",
))]
vulkan: u32,
#[cfg(any(target_os = "ios", target_os = "macos"))]
metal: u32,
#[cfg(windows)]
dx12: u32,
#[cfg(windows)]
dx11: u32,
}
let test_foo: Foo = backends_map! {
let map = |init| { init - 100 };
Foo {
#[vulkan] vulkan: map(101),
#[metal] metal: map(102),
#[dx12] dx12: map(103),
#[dx11] dx11: map(104),
}
};
let mut vec = Vec::new();
backends_map! {
let map = |(id, chr)| {
vec.push((id, chr));
};
#[vulkan]
map((test_foo.vulkan, 'a')),
#[metal]
map((test_foo.metal, 'b')),
#[dx12]
map((test_foo.dx12, 'c')),
#[dx11]
map((test_foo.dx11, 'd')),
}
#[cfg(any(
windows,
all(unix, not(any(target_os = "ios", target_os = "macos"))),
feature = "gfx-backend-vulkan",
))]
assert!(vec.contains(&(1, 'a')));
#[cfg(any(target_os = "ios", target_os = "macos"))]
assert!(vec.contains(&(2, 'b')));
#[cfg(windows)]
assert!(vec.contains(&(3, 'c')));
#[cfg(windows)]
assert!(vec.contains(&(4, 'd')));
backends_map! {
let map = |(id, pred, code)| {
if pred(id) {
code();
}
};
#[vulkan]
map((test_foo.vulkan, |v| v == 1, || println!("vulkan"))),
#[metal]
map((test_foo.metal, |v| v == 2, || println!("metal"))),
#[dx12]
map((test_foo.dx12, |v| v == 3, || println!("dx12"))),
#[dx11]
map((test_foo.dx11, |v| v == 4, || println!("dx11"))),
}
let test_foo_2: Foo = backends! {
Foo {
#[vulkan]
vulkan: 1,
#[metal]
metal: 2,
#[dx12]
dx12: 3,
#[dx11]
dx11: 4,
}
};
backends! {
#[vulkan]
let var_vulkan = test_foo_2.vulkan;
#[metal]
let var_metal = test_foo_2.metal;
#[dx12]
let var_dx12 = test_foo_2.dx12;
#[dx11]
let var_dx11 = test_foo_2.dx11;
}
backends_map! {
let map = |(id, chr, var)| { (chr, id, var) };
#[vulkan]
let var_vulkan = map((test_foo_2.vulkan, 'a', var_vulkan));
#[metal]
let var_metal = map((test_foo_2.metal, 'b', var_metal));
#[dx12]
let var_dx12 = map((test_foo_2.dx12, 'c', var_dx12));
#[dx11]
let var_dx11 = map((test_foo_2.dx11, 'd', var_dx11));
}
backends! {
#[vulkan]
{
println!("backend int: {:?}", var_vulkan);
}
#[metal]
{
println!("backend int: {:?}", var_metal);
}
#[dx12]
{
println!("backend int: {:?}", var_dx12);
}
#[dx11]
{
println!("backend int: {:?}", var_dx11);
}
}
#[cfg(any(
windows,
all(unix, not(any(target_os = "ios", target_os = "macos"))),
feature = "gfx-backend-vulkan",
))]
let _ = var_vulkan;
#[cfg(any(target_os = "ios", target_os = "macos"))]
let _ = var_metal;
#[cfg(windows)]
let _ = var_dx12;
#[cfg(windows)]
let _ = var_dx11;
}