use std::mem::size_of;
use crate as sys;
use crate::static_assert;
pub fn u32_to_usize(i: u32) -> usize {
static_assert!(
size_of::<u32>() <= size_of::<usize>(),
"gdext only supports targets where u32 <= usize"
);
unsafe { i.try_into().unwrap_unchecked() }
}
pub const fn bool_to_sys(value: bool) -> sys::GDExtensionBool {
value as sys::GDExtensionBool
}
pub fn bool_from_sys(value: sys::GDExtensionBool) -> bool {
match value {
SYS_TRUE => true,
SYS_FALSE => false,
_ => panic!("Invalid GDExtensionBool value: {value}"),
}
}
#[cfg(since_api = "4.3")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.3")))]
pub fn ptr_list_into_sys<T>(list: Vec<T>) -> (*const T, u32) {
let len: u32 = list
.len()
.try_into()
.expect("list must have length that fits in u32");
let ptr = Box::leak(list.into_boxed_slice()).as_ptr();
(ptr, len)
}
#[cfg(since_api = "4.3")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.3")))]
pub unsafe fn ptr_list_from_sys<T>(ptr: *const T, len: u32) -> Box<[T]> {
let ptr: *mut T = ptr.cast_mut();
let len: usize = sys::conv::u32_to_usize(len);
let slice = unsafe { std::slice::from_raw_parts_mut(ptr, len) };
unsafe { Box::from_raw(slice) }
}
pub const SYS_TRUE: sys::GDExtensionBool = bool_to_sys(true);
pub const SYS_FALSE: sys::GDExtensionBool = bool_to_sys(false);
#[cfg(test)] #[cfg_attr(published_docs, doc(cfg(test)))]
mod test {
use crate::conv::{SYS_FALSE, SYS_TRUE, bool_to_sys, u32_to_usize};
#[test]
fn sys_bool() {
assert_eq!(bool_to_sys(true), SYS_TRUE);
assert_eq!(bool_to_sys(false), SYS_FALSE);
}
#[test]
fn u32_into_usize_test() {
const CHECKS: &[u32] = &[
0,
123,
4444,
u32::MAX,
u16::MAX as u32,
u8::MAX as u32,
i8::MAX as u32,
i16::MAX as u32,
i32::MAX as u32,
];
for value in CHECKS {
assert_eq!(u32_to_usize(*value), *value as usize);
assert_eq!(u32_to_usize(*value) as u32, *value);
}
}
}