diff --git a/src/v2_types/any_type.rs b/src/v2_types/any_type.rs new file mode 100644 index 0000000..a300249 --- /dev/null +++ b/src/v2_types/any_type.rs @@ -0,0 +1,479 @@ +use super::*; + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum AnyNumericProperty { + U8(UByteProperty), + U16(UUInt16Property), + U32(UUInt32Property), + U64(UUInt64Property), + I8(UInt8Property), + I16(UInt16Property), + I32(UIntProperty), + I64(UInt64Property), + F32(UFloatProperty), + F64(UDoubleProperty), + Other(UNumericProperty), +} + +impl UObjectTrait for AnyNumericProperty {} +impl UFieldTrait for AnyNumericProperty {} +impl UPropertyTrait for AnyNumericProperty {} +impl UNumericPropertyTrait for AnyNumericProperty {} + +impl AsUObject for AnyNumericProperty { + fn as_uobject(&self) -> self::UObject { + match self { + Self::U8(obj) => obj.as_uobject(), + Self::U16(obj) => obj.as_uobject(), + Self::U32(obj) => obj.as_uobject(), + Self::U64(obj) => obj.as_uobject(), + Self::I8(obj) => obj.as_uobject(), + Self::I16(obj) => obj.as_uobject(), + Self::I32(obj) => obj.as_uobject(), + Self::I64(obj) => obj.as_uobject(), + Self::F32(obj) => obj.as_uobject(), + Self::F64(obj) => obj.as_uobject(), + Self::Other(obj) => obj.as_uobject(), + } + } + + fn from_raw(raw: *mut ()) -> Option { + UNumericProperty::from_raw(raw).map(|obj| Self::from_prop(obj)) + } + + fn from_nonnull(raw: NonNull>) -> Self { + Self::from_prop(UNumericProperty::from_nonnull(raw)) + } +} + +impl AnyNumericProperty { + fn from_prop(prop: UNumericProperty) -> Self { + if prop.is_a_maybe(&UByteProperty::static_class()) { + Self::U8(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UUInt16Property::static_class()) { + Self::U16(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UUInt32Property::static_class()) { + Self::U32(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UUInt64Property::static_class()) { + Self::U64(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UInt8Property::static_class()) { + Self::I8(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UInt16Property::static_class()) { + Self::I16(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UIntProperty::static_class()) { + Self::I32(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UInt64Property::static_class()) { + Self::I64(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UFloatProperty::static_class()) { + Self::F32(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UDoubleProperty::static_class()) { + Self::F64(unsafe { prop.cast() }) + } else { + Self::Other(prop) + } + } +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum AnyObjectProperty { + Class(UClassProperty), + Object(UObjectProperty), +} + +impl UObjectTrait for AnyObjectProperty {} +impl UFieldTrait for AnyObjectProperty {} +impl UPropertyTrait for AnyObjectProperty {} +impl UObjectPropertyBaseTrait for AnyObjectProperty {} +impl UObjectPropertyTrait for AnyObjectProperty {} + +impl AsUObject for AnyObjectProperty { + fn as_uobject(&self) -> self::UObject { + match self { + Self::Class(obj) => obj.as_uobject(), + Self::Object(obj) => obj.as_uobject(), + } + } + + fn from_raw(raw: *mut ()) -> Option { + UObjectProperty::from_raw(raw).map(|obj| Self::from_prop(obj)) + } + + fn from_nonnull(raw: NonNull>) -> Self { + Self::from_prop(UObjectProperty::from_nonnull(raw)) + } +} + +impl AnyObjectProperty { + pub fn from_prop(prop: UObjectProperty) -> Self { + if prop.is_a_maybe(&UClassProperty::static_class()) { + Self::Class(unsafe { prop.cast() }) + } else { + Self::Object(unsafe { prop.cast() }) + } + } +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum AnyAssetObjectProperty { + Class(UAssetClassProperty), + Object(UAssetObjectProperty), +} + +impl UObjectTrait for AnyAssetObjectProperty {} +impl UFieldTrait for AnyAssetObjectProperty {} +impl UPropertyTrait for AnyAssetObjectProperty {} +impl UObjectPropertyBaseTrait for AnyAssetObjectProperty {} +impl UAssetObjectPropertyTrait for AnyAssetObjectProperty {} + +impl AsUObject for AnyAssetObjectProperty { + fn as_uobject(&self) -> self::UObject { + match self { + Self::Class(obj) => obj.as_uobject(), + Self::Object(obj) => obj.as_uobject(), + } + } + + fn from_raw(raw: *mut ()) -> Option { + UAssetObjectProperty::from_raw(raw).map(|obj| Self::from_prop(obj)) + } + + fn from_nonnull(raw: NonNull>) -> Self { + Self::from_prop(UAssetObjectProperty::from_nonnull(raw)) + } +} + +impl AnyAssetObjectProperty { + pub fn from_prop(prop: UAssetObjectProperty) -> Self { + if prop.is_a_maybe(&UAssetClassProperty::static_class()) { + Self::Class(unsafe { prop.cast() }) + } else { + Self::Object(unsafe { prop.cast() }) + } + } +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum AnyObjectBaseProperty { + Object(UObjectProperty), // into AnyObjectProp + WeakObject(UWeakObjectProperty), + LazyObject(ULazyObjectProperty), + SoftObject(USoftObjectProperty), + AssetObject(UAssetObjectProperty), // into AnyAssetObjectProp + Other(UObjectPropertyBase), +} + +impl UObjectTrait for AnyObjectBaseProperty {} +impl UFieldTrait for AnyObjectBaseProperty {} +impl UPropertyTrait for AnyObjectBaseProperty {} +impl UObjectPropertyBaseTrait for AnyObjectBaseProperty {} + +impl AsUObject for AnyObjectBaseProperty { + fn as_uobject(&self) -> self::UObject { + match self { + Self::Object(obj) => obj.as_uobject(), + Self::WeakObject(obj) => obj.as_uobject(), + Self::LazyObject(obj) => obj.as_uobject(), + Self::SoftObject(obj) => obj.as_uobject(), + Self::AssetObject(obj) => obj.as_uobject(), + Self::Other(obj) => obj.as_uobject(), + } + } + + fn from_raw(raw: *mut ()) -> Option { + UObjectPropertyBase::from_raw(raw).map(|obj| Self::from_prop(obj)) + } + + fn from_nonnull(raw: NonNull>) -> Self { + Self::from_prop(UObjectPropertyBase::from_nonnull(raw)) + } +} + +impl AnyObjectBaseProperty { + pub fn as_any_object_property(&self) -> Option { + match self { + Self::Object(obj) => Some(AnyObjectProperty::from_prop(*obj)), + _ => None, + } + } + + pub fn as_any_asset_object_property(&self) -> Option { + match self { + Self::AssetObject(obj) => Some(AnyAssetObjectProperty::from_prop(*obj)), + _ => None, + } + } + + pub fn from_prop(prop: UObjectPropertyBase) -> Self { + if prop.is_a_maybe(&UAssetObjectProperty::static_class()) { + Self::AssetObject(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UWeakObjectProperty::static_class()) { + Self::WeakObject(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&ULazyObjectProperty::static_class()) { + Self::LazyObject(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&USoftObjectProperty::static_class()) { + Self::SoftObject(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UObjectProperty::static_class()) { + Self::Object(unsafe { prop.cast() }) + } else { + Self::Other(prop) + } + } +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum AnyProperty { + Numeric(UNumericProperty), // into AnyNumericProp + Bool(UBoolProperty), + Interface(UInterfaceProperty), + ObjectBase(UObjectPropertyBase), // into AnyObjectBaseProp + Array(UArrayProperty), + Map(UMapProperty), + Str(UStrProperty), + Text(UTextProperty), + Name(UNameProperty), + Delegate(UDelegateProperty), + MulticastDelegate(UMulticastDelegateProperty), + Enum(UEnumProperty), + Struct(UStructProperty), + Other(UProperty), +} + +impl UObjectTrait for AnyProperty {} +impl UFieldTrait for AnyProperty {} +impl UPropertyTrait for AnyProperty {} + +impl AsUObject for AnyProperty { + fn as_uobject(&self) -> self::UObject { + match self { + Self::Numeric(obj) => obj.as_uobject(), + Self::Bool(obj) => obj.as_uobject(), + Self::Interface(obj) => obj.as_uobject(), + Self::ObjectBase(obj) => obj.as_uobject(), + Self::Array(obj) => obj.as_uobject(), + Self::Map(obj) => obj.as_uobject(), + Self::Str(obj) => obj.as_uobject(), + Self::Text(obj) => obj.as_uobject(), + Self::Name(obj) => obj.as_uobject(), + Self::Delegate(obj) => obj.as_uobject(), + Self::MulticastDelegate(obj) => obj.as_uobject(), + Self::Enum(obj) => obj.as_uobject(), + Self::Struct(obj) => obj.as_uobject(), + Self::Other(obj) => obj.as_uobject(), + } + } + + fn from_raw(raw: *mut ()) -> Option { + UProperty::from_raw(raw).map(|obj| Self::from_prop(obj)) + } + + fn from_nonnull(raw: NonNull>) -> Self { + Self::from_prop(UProperty::from_nonnull(raw)) + } +} + +impl Display for AnyProperty { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&unsafe { self.as_uobject().cast::() }, f) + } +} + +impl AnyProperty { + pub fn as_any_numeric_property(&self) -> Option { + match self { + Self::Numeric(obj) => Some(AnyNumericProperty::from_prop(*obj)), + _ => None, + } + } + + pub fn as_any_object_base_property(&self) -> Option { + match self { + Self::ObjectBase(obj) => Some(AnyObjectBaseProperty::from_prop(*obj)), + _ => None, + } + } + + pub fn from_prop(prop: UProperty) -> Self { + if prop.is_a_maybe(&UNumericProperty::static_class()) { + Self::Numeric(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UBoolProperty::static_class()) { + Self::Bool(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UInterfaceProperty::static_class()) { + Self::Interface(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UObjectPropertyBase::static_class()) { + Self::ObjectBase(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UArrayProperty::static_class()) { + Self::Array(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UMapProperty::static_class()) { + Self::Map(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UDelegateProperty::static_class()) { + Self::Delegate(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UMulticastDelegateProperty::static_class()) { + Self::MulticastDelegate(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UStrProperty::static_class()) { + Self::Str(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UNameProperty::static_class()) { + Self::Name(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UTextProperty::static_class()) { + Self::Text(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UStructProperty::static_class()) { + Self::Struct(unsafe { prop.cast() }) + } else if prop.is_a_maybe(&UEnumProperty::static_class()) { + Self::Enum(unsafe { prop.cast() }) + } else { + Self::Other(prop) + } + } +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum AnyStruct { + ScriptStruct(UScriptStruct), + Class(UClass), + Function(UFunction), + Other(UStruct), +} + +impl UObjectTrait for AnyStruct {} +impl UFieldTrait for AnyStruct {} +impl UStructTrait for AnyStruct {} + +impl AsUObject for AnyStruct { + fn as_uobject(&self) -> self::UObject { + match self { + Self::ScriptStruct(obj) => obj.as_uobject(), + Self::Class(obj) => obj.as_uobject(), + Self::Function(obj) => obj.as_uobject(), + Self::Other(obj) => obj.as_uobject(), + } + } + + fn from_raw(raw: *mut ()) -> Option { + UStruct::from_raw(raw).map(|obj| Self::from_struct(obj)) + } + + fn from_nonnull(raw: NonNull>) -> Self { + Self::from_struct(UStruct::from_nonnull(raw)) + } +} + +impl AnyStruct { + pub fn from_struct(obj: UStruct) -> Self { + if obj.is_a_maybe(&UScriptStruct::static_class()) { + Self::ScriptStruct(unsafe { obj.cast() }) + } else if obj.is_a_maybe(&UClass::static_class()) { + Self::Class(unsafe { obj.cast() }) + } else if obj.is_a_maybe(&UFunction::static_class()) { + Self::Function(unsafe { obj.cast() }) + } else { + Self::Other(obj) + } + } +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum AnyField { + Property(UProperty), // into AnyProperty + Enum(UEnum), + Struct(UStruct), // into AnyStruct + Other(UField), +} + +impl UObjectTrait for AnyField {} +impl UFieldTrait for AnyField {} + +impl AsUObject for AnyField { + fn as_uobject(&self) -> self::UObject { + match self { + Self::Property(obj) => obj.as_uobject(), + Self::Enum(obj) => obj.as_uobject(), + Self::Struct(obj) => obj.as_uobject(), + Self::Other(obj) => obj.as_uobject(), + } + } + + fn from_raw(raw: *mut ()) -> Option { + UField::from_raw(raw).map(|obj| Self::from_field(obj)) + } + + fn from_nonnull(raw: NonNull>) -> Self { + Self::from_field(UField::from_nonnull(raw)) + } +} + +impl AnyField { + pub fn from_field(obj: UField) -> Self { + if obj.is_a_maybe(&UProperty::static_class()) { + Self::Property(unsafe { obj.cast() }) + } else if obj.is_a_maybe(&UEnum::static_class()) { + Self::Enum(unsafe { obj.cast() }) + } else if obj.is_a_maybe(&UStruct::static_class()) { + Self::Struct(unsafe { obj.cast() }) + } else { + Self::Other(obj) + } + } + + pub fn as_any_property(&self) -> Option { + match self { + Self::Property(obj) => Some(AnyProperty::from_prop(*obj)), + _ => None, + } + } + + pub fn as_any_struct(&self) -> Option { + match self { + Self::Struct(obj) => Some(AnyStruct::from_struct(*obj)), + _ => None, + } + } +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum AnyObject { + Field(UField), // into AnyField + Other(UObject), +} + +impl UObjectTrait for AnyObject {} + +impl AsUObject for AnyObject { + fn as_uobject(&self) -> self::UObject { + match self { + Self::Field(obj) => obj.as_uobject(), + Self::Other(obj) => obj.as_uobject(), + } + } + + fn from_raw(raw: *mut ()) -> Option { + UObject::from_raw(raw).map(|obj| Self::from_object(obj)) + } + + fn from_nonnull(raw: NonNull>) -> Self { + Self::from_object(UObject::from_nonnull(raw)) + } +} + +impl AnyObject { + pub fn from_object(obj: UObject) -> Self { + if obj.is_a_maybe(&UField::static_class()) { + Self::Field(unsafe { obj.cast() }) + } else { + Self::Other(obj) + } + } + + pub fn as_any_field(&self) -> Option { + match self { + AnyObject::Field(field) => Some(AnyField::from_field(*field)), + _ => None, + } + } +} diff --git a/src/v2_types/mod.rs b/src/v2_types/mod.rs index a41b5d8..9d68a1d 100644 --- a/src/v2_types/mod.rs +++ b/src/v2_types/mod.rs @@ -14,6 +14,8 @@ use std::{ ptr::NonNull, }; +pub mod any_type; + #[derive(Debug)] #[repr(transparent)] pub struct VTbl(NonNull<()>);