ash

Macro match_out_struct

Source
macro_rules! match_out_struct {
    (match $p:ident { $($bind:ident @ $ty:path => $body:block $(,)?)+ $(_ => $any:block $(,)?)? }) => { ... };
}
Expand description

Given a mutable raw pointer to a type with an s_type member such as vk::BaseOutStructure, match on a set of Vulkan structures. The struct will be rebound to the given variable of the type of the given Vulkan structure.

Note that all match bodies have to be enclosed by curly braces due to macro parsing limitations. It is unfortunately not possible to write x @ ash::vk::SomeStruct => one_line_expression(),.

let mut info = ash::vk::DeviceCreateInfo::default();
let info: *mut ash::vk::BaseOutStructure = <*mut _>::cast(&mut info);
unsafe {
    ash::match_out_struct!(match info {
        info @ ash::vk::DeviceQueueCreateInfo => {
            dbg!(&info); // Unreachable
        }
        info @ ash::vk::DeviceCreateInfo => {
            dbg!(&info);
        }
    })
}

In addition this macro propagates implicit return values just like normal match blocks, as long as a default value or expression is provided in the “any” match arm (_ => { some_value() }). For the time being said arm must be wrapped in curly braces; an expression like _ => None is not yet supported.

let device_create_flags: Option<ash::vk::DeviceCreateFlags> = unsafe {
    ash::match_out_struct!(match info {
        info @ ash::vk::DeviceQueueCreateInfo => {
            dbg!(&info); // Unreachable
            Some(ash::vk::DeviceCreateFlags::empty())
        }
        info @ ash::vk::DeviceCreateInfo => {
            dbg!(&info);
            Some(info.flags)
        }
        _ => {
            None
        }
    })
};