use std::num::NonZeroU64;
use godot_ffi as sys;
use sys::{ExtVariantType, GodotFfi, ffi_methods, static_assert, static_assert_eq_size_align};
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum Rid {
Valid(NonZeroU64),
Invalid,
}
static_assert_eq_size_align!(Rid, u64);
static_assert!(unsafe { std::mem::transmute::<Rid, u64>(Rid::Invalid) } == 0u64);
impl Rid {
#[inline]
pub const fn new(id: u64) -> Self {
match NonZeroU64::new(id) {
Some(id) => Self::Valid(id),
None => Self::Invalid,
}
}
#[doc(alias = "get_id")]
#[inline]
pub const fn to_u64(self) -> u64 {
match self {
Rid::Valid(id) => id.get(),
Rid::Invalid => 0,
}
}
#[inline]
pub const fn to_valid_u64(self) -> Option<u64> {
match self {
Rid::Valid(id) => Some(id.get()),
Rid::Invalid => None,
}
}
#[inline]
pub const fn is_valid(&self) -> bool {
matches!(self, Rid::Valid(_))
}
#[inline]
pub const fn is_invalid(&self) -> bool {
matches!(self, Rid::Invalid)
}
}
impl std::fmt::Display for Rid {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Rid::Valid(x) => write!(f, "RID({x})"),
Rid::Invalid => write!(f, "RID(0)"),
}
}
}
unsafe impl GodotFfi for Rid {
const VARIANT_TYPE: ExtVariantType = ExtVariantType::Concrete(sys::VariantType::RID);
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self;
fn new_from_sys;
fn new_with_uninit;
fn from_arg_ptr;
fn sys;
fn sys_mut;
fn move_return_ptr;
}
unsafe fn new_with_init(init: impl FnOnce(sys::GDExtensionTypePtr)) -> Self {
let mut rid = Self::Invalid;
init(rid.sys_mut());
rid
}
}
crate::meta::impl_godot_as_self!(Rid: ByValue);