diff --git a/src/types/id/tweak_db_id.rs b/src/types/id/tweak_db_id.rs index a161fb6..b268e40 100644 --- a/src/types/id/tweak_db_id.rs +++ b/src/types/id/tweak_db_id.rs @@ -76,6 +76,32 @@ impl TweakDbId { pub(super) const fn to_inner(self) -> red::TweakDBID { self.0 } + + /// Available post RTTI registration. + /// + /// see [TDBID.ToStringDEBUG](https://nativedb.red4ext.com/gamedataTDBIDHelper#ToStringDEBUG) + #[cfg(not(test))] + pub fn to_string_debug(&self) -> Result { + const CLS_NAME: &str = "gamedataTDBIDHelper"; + const FUN_NAME: &str = "ToStringDEBUG"; + const FUN_CNAME: crate::types::CName = crate::types::CName::new(FUN_NAME); + let rtti = crate::RttiSystem::get(); + let class = rtti + .get_class(crate::types::CName::new(CLS_NAME)) + .ok_or(crate::InvokeError::ClassNotFound(CLS_NAME))?; + let method = class + .methods() + .iter() + .find(|x| x.as_function().name() == FUN_CNAME) + .ok_or(crate::InvokeError::FunctionNotFound(FUN_NAME))?; + let mut out = crate::types::RedString::new(); + let out_ptr = &raw mut out; + let out_ptr = unsafe { &*out_ptr.cast::() }; + method + .as_function() + .execute::<_, crate::types::RedString>(Some(out_ptr), (*self,)) + .map(|x| x.to_string()) + } } impl Debug for TweakDbId { @@ -86,6 +112,16 @@ impl Debug for TweakDbId { } } +impl std::fmt::Display for TweakDbId { + fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + #[cfg(not(test))] + if let Ok(id) = self.to_string_debug() { + return write!(_f, "{id}"); + } + std::fmt::Result::Ok(()) + } +} + impl PartialEq for TweakDbId { fn eq(&self, other: &Self) -> bool { u64::from(*self).eq(&u64::from(*other))