use std::ffi::CString;
use d3d11_ffi::core_supplemental::PCSTR;
pub fn wrap_option_out_result<T, F>(f: F) -> d3d11_ffi::core::Result<T>
where
F: FnOnce(Option<*mut Option<T>>) -> d3d11_ffi::core::Result<()>,
{
let mut result = None;
f(Some(&raw mut result))?;
Ok(result.unwrap())
}
pub fn wrap_out_result<T, F>(f: F) -> d3d11_ffi::core::Result<T>
where
F: FnOnce(*mut Option<T>) -> d3d11_ffi::core::Result<()>,
{
let mut result = None;
f(&raw mut result)?;
Ok(result.unwrap())
}
pub fn wrap_out_ptr<T: Default, F>(f: F) -> d3d11_ffi::core::Result<T>
where
F: FnOnce(*mut T) -> d3d11_ffi::core::Result<()>,
{
let mut result = T::default();
f(&raw mut result)?;
Ok(result)
}
#[macro_export]
macro_rules! verify_ffi_struct {
($struct:ident, $ffi:ident) => {
static_assertions::assert_eq_size!($struct, $ffi);
impl $struct {
#[allow(dead_code)]
pub(crate) fn as_ffi(&self) -> *const $ffi {
self as *const _ as _
}
}
};
}
pub fn to_pcstr<S>(s: S) -> (CString, PCSTR)
where
S: AsRef<str>,
{
let cstr = CString::new(s.as_ref()).expect("Failed to convert string to CString");
let pcstr = cstr.as_ptr();
(cstr, PCSTR::from_raw(pcstr as _))
}
pub trait OptionalParam: Sized {
type Output;
fn as_option(&self) -> Option<&Self::Output>;
}
impl<T> OptionalParam for &T {
type Output = T;
fn as_option(&self) -> Option<&Self::Output> {
Some(self)
}
}
impl<T> OptionalParam for Option<&T> {
type Output = T;
fn as_option(&self) -> Option<&Self::Output> {
*self
}
}
#[macro_export]
macro_rules! cast_optional_resource_refs {
($stack_count:expr, $input_slice:ident) => {
if $input_slice.len() > 1 {
type TempStorage =
smallvec::SmallVec<[Option<std::ptr::NonNull<std::ffi::c_void>>; $stack_count]>;
let mut temp_storage = TempStorage::with_capacity($input_slice.len());
for res in $input_slice.iter() {
let ptr = res.as_ref().map(|b| std::mem::transmute_copy(*b));
temp_storage.push(ptr);
}
temp_storage
} else {
let ptr: Option<std::ptr::NonNull<std::ffi::c_void>> = $input_slice
.get(0)
.and_then(|res| res.as_ref().map(|b| std::mem::transmute_copy(*b)));
smallvec::smallvec![ptr]
}
};
}