diff --git a/crates/lune-roblox/src/datatypes/attributes.rs b/crates/lune-roblox/src/datatypes/attributes.rs index 7d5bd26..f7b0fc4 100644 --- a/crates/lune-roblox/src/datatypes/attributes.rs +++ b/crates/lune-roblox/src/datatypes/attributes.rs @@ -47,6 +47,7 @@ pub fn ensure_valid_attribute_value(value: &DomValue) -> LuaResult<()> { | DomType::CFrame | DomType::Color3 | DomType::ColorSequence + | DomType::EnumItem | DomType::Float32 | DomType::Float64 | DomType::Font diff --git a/crates/lune-roblox/src/datatypes/conversion.rs b/crates/lune-roblox/src/datatypes/conversion.rs index dbd4249..201ab00 100644 --- a/crates/lune-roblox/src/datatypes/conversion.rs +++ b/crates/lune-roblox/src/datatypes/conversion.rs @@ -201,6 +201,7 @@ impl<'lua> DomValueToLua<'lua> for LuaAnyUserData<'lua> { DomValue::Color3uint8(value) => dom_to_userdata!(lua, value => Color3), DomValue::ColorSequence(value) => dom_to_userdata!(lua, value => ColorSequence), DomValue::Content(value) => dom_to_userdata!(lua, value => Content), + DomValue::EnumItem(value) => dom_to_userdata!(lua, value => EnumItem), DomValue::Faces(value) => dom_to_userdata!(lua, value => Faces), DomValue::Font(value) => dom_to_userdata!(lua, value => Font), DomValue::NumberRange(value) => dom_to_userdata!(lua, value => NumberRange), @@ -258,7 +259,7 @@ impl<'lua> LuaToDomValue<'lua> for LuaAnyUserData<'lua> { DomType::Color3uint8 => userdata_to_dom!(self as Color3 => dom::Color3uint8), DomType::ColorSequence => userdata_to_dom!(self as ColorSequence => dom::ColorSequence), DomType::Content => userdata_to_dom!(self as Content => dom::Content), - DomType::Enum => userdata_to_dom!(self as EnumItem => dom::Enum), + DomType::EnumItem => userdata_to_dom!(self as EnumItem => dom::EnumItem), DomType::Faces => userdata_to_dom!(self as Faces => dom::Faces), DomType::Font => userdata_to_dom!(self as Font => dom::Font), DomType::NumberRange => userdata_to_dom!(self as NumberRange => dom::NumberRange), @@ -316,7 +317,7 @@ impl<'lua> LuaToDomValue<'lua> for LuaAnyUserData<'lua> { value if value.is::() => userdata_to_dom!(value as CFrame => dom::CFrame), value if value.is::() => userdata_to_dom!(value as Color3 => dom::Color3), value if value.is::() => userdata_to_dom!(value as ColorSequence => dom::ColorSequence), - value if value.is::() => userdata_to_dom!(value as EnumItem => dom::Enum), + value if value.is::() => userdata_to_dom!(value as EnumItem => dom::EnumItem), value if value.is::() => userdata_to_dom!(value as Faces => dom::Faces), value if value.is::() => userdata_to_dom!(value as Font => dom::Font), value if value.is::() => userdata_to_dom!(value as Instance => dom::Ref), diff --git a/crates/lune-roblox/src/datatypes/extension.rs b/crates/lune-roblox/src/datatypes/extension.rs index 30bb916..2ad1125 100644 --- a/crates/lune-roblox/src/datatypes/extension.rs +++ b/crates/lune-roblox/src/datatypes/extension.rs @@ -21,6 +21,7 @@ impl DomValueExt for DomType { Content => "Content", ContentId => "ContentId", Enum => "Enum", + EnumItem => "EnumItem", Faces => "Faces", Float32 => "Float32", Float64 => "Float64", diff --git a/crates/lune-roblox/src/datatypes/types/enum_item.rs b/crates/lune-roblox/src/datatypes/types/enum_item.rs index 7089ccc..c403f55 100644 --- a/crates/lune-roblox/src/datatypes/types/enum_item.rs +++ b/crates/lune-roblox/src/datatypes/types/enum_item.rs @@ -1,7 +1,7 @@ use core::fmt; use mlua::prelude::*; -use rbx_dom_weak::types::Enum as DomEnum; +use rbx_dom_weak::types::EnumItem as DomEnumItem; use super::{super::*, Enum}; @@ -100,8 +100,18 @@ impl PartialEq for EnumItem { } } -impl From for DomEnum { +impl From for DomEnumItem { fn from(v: EnumItem) -> Self { - DomEnum::from_u32(v.value) + DomEnumItem { + ty: v.parent.desc.name.to_string(), + value: v.value, + } + } +} + +impl From for EnumItem { + fn from(value: DomEnumItem) -> Self { + EnumItem::from_enum_name_and_value(value.ty, value.value) + .expect("cannot convert rbx_type::EnumItem with unknown type into EnumItem") } } diff --git a/crates/lune-roblox/src/instance/base.rs b/crates/lune-roblox/src/instance/base.rs index 773bf27..1a10096 100644 --- a/crates/lune-roblox/src/instance/base.rs +++ b/crates/lune-roblox/src/instance/base.rs @@ -331,7 +331,7 @@ fn instance_property_set<'lua>( if let Some(enum_name) = info.enum_name { match LuaUserDataRef::::from_lua(prop_value, lua) { Ok(given_enum) if given_enum.parent.desc.name == enum_name => { - this.set_property(prop_name, DomValue::Enum((*given_enum).clone().into())); + this.set_property(prop_name, DomValue::EnumItem((*given_enum).clone().into())); Ok(()) } Ok(given_enum) => Err(LuaError::RuntimeError(format!( diff --git a/tests/roblox/instance/attributes.luau b/tests/roblox/instance/attributes.luau index 4c0a62f..c62c879 100644 --- a/tests/roblox/instance/attributes.luau +++ b/tests/roblox/instance/attributes.luau @@ -16,6 +16,7 @@ local UDim2 = roblox.UDim2 local Vector2 = roblox.Vector2 local Vector3 = roblox.Vector3 local Instance = roblox.Instance +local Enum = roblox.Enum local modelFile = fs.readFile("tests/roblox/rbx-test-files/models/attributes/binary.rbxm") local model = roblox.deserializeModel(modelFile)[1] @@ -114,3 +115,12 @@ model.Parent = game local placeFile = roblox.serializePlace(game) fs.writeDir("bin/roblox") fs.writeFile("bin/roblox/attributes.rbxl", placeFile) + +local enum_attr = Instance.new("Folder") +enum_attr:SetAttribute("Foo", Enum.NormalId.Front) +assert(enum_attr:GetAttribute("Foo") == Enum.NormalId.Front) + +local enum_attr_ser = roblox.serializeModel({ enum_attr }) +local enum_attr_de = roblox.deserializeModel(enum_attr_ser) + +assert(enum_attr_de[1]:GetAttribute("Foo") == Enum.NormalId.Front) diff --git a/tests/roblox/instance/properties.luau b/tests/roblox/instance/properties.luau index 40709a7..576b15b 100644 --- a/tests/roblox/instance/properties.luau +++ b/tests/roblox/instance/properties.luau @@ -33,6 +33,16 @@ part.Shape = Enum.PartType.Ball assert(part.Shape == Enum.PartType.Ball) +-- Enums should roundtrip through serde without problem + +local decal = Instance.new("Decal") +decal.Face = Enum.NormalId.Top + +local decal_ser = roblox.serializeModel({ decal }) +local decal_de = roblox.deserializeModel(decal_ser) + +assert(decal_de[1].Face == Enum.NormalId.Top) + -- Properties that don't exist for a class should error local meshPart = Instance.new("MeshPart")