Implement Enum attributes (#306)

This commit is contained in:
Micah 2025-04-03 13:14:24 -07:00 committed by GitHub
parent 8bd1a9b77d
commit 27e3efca97
Signed by: DevComp
GPG key ID: B5690EEEBB952194
7 changed files with 39 additions and 6 deletions

View file

@ -47,6 +47,7 @@ pub fn ensure_valid_attribute_value(value: &DomValue) -> LuaResult<()> {
| DomType::CFrame | DomType::CFrame
| DomType::Color3 | DomType::Color3
| DomType::ColorSequence | DomType::ColorSequence
| DomType::EnumItem
| DomType::Float32 | DomType::Float32
| DomType::Float64 | DomType::Float64
| DomType::Font | DomType::Font

View file

@ -201,6 +201,7 @@ impl<'lua> DomValueToLua<'lua> for LuaAnyUserData<'lua> {
DomValue::Color3uint8(value) => dom_to_userdata!(lua, value => Color3), DomValue::Color3uint8(value) => dom_to_userdata!(lua, value => Color3),
DomValue::ColorSequence(value) => dom_to_userdata!(lua, value => ColorSequence), DomValue::ColorSequence(value) => dom_to_userdata!(lua, value => ColorSequence),
DomValue::Content(value) => dom_to_userdata!(lua, value => Content), 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::Faces(value) => dom_to_userdata!(lua, value => Faces),
DomValue::Font(value) => dom_to_userdata!(lua, value => Font), DomValue::Font(value) => dom_to_userdata!(lua, value => Font),
DomValue::NumberRange(value) => dom_to_userdata!(lua, value => NumberRange), 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::Color3uint8 => userdata_to_dom!(self as Color3 => dom::Color3uint8),
DomType::ColorSequence => userdata_to_dom!(self as ColorSequence => dom::ColorSequence), DomType::ColorSequence => userdata_to_dom!(self as ColorSequence => dom::ColorSequence),
DomType::Content => userdata_to_dom!(self as Content => dom::Content), 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::Faces => userdata_to_dom!(self as Faces => dom::Faces),
DomType::Font => userdata_to_dom!(self as Font => dom::Font), DomType::Font => userdata_to_dom!(self as Font => dom::Font),
DomType::NumberRange => userdata_to_dom!(self as NumberRange => dom::NumberRange), 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::<CFrame>() => userdata_to_dom!(value as CFrame => dom::CFrame), value if value.is::<CFrame>() => userdata_to_dom!(value as CFrame => dom::CFrame),
value if value.is::<Color3>() => userdata_to_dom!(value as Color3 => dom::Color3), value if value.is::<Color3>() => userdata_to_dom!(value as Color3 => dom::Color3),
value if value.is::<ColorSequence>() => userdata_to_dom!(value as ColorSequence => dom::ColorSequence), value if value.is::<ColorSequence>() => userdata_to_dom!(value as ColorSequence => dom::ColorSequence),
value if value.is::<Enum>() => userdata_to_dom!(value as EnumItem => dom::Enum), value if value.is::<EnumItem>() => userdata_to_dom!(value as EnumItem => dom::EnumItem),
value if value.is::<Faces>() => userdata_to_dom!(value as Faces => dom::Faces), value if value.is::<Faces>() => userdata_to_dom!(value as Faces => dom::Faces),
value if value.is::<Font>() => userdata_to_dom!(value as Font => dom::Font), value if value.is::<Font>() => userdata_to_dom!(value as Font => dom::Font),
value if value.is::<Instance>() => userdata_to_dom!(value as Instance => dom::Ref), value if value.is::<Instance>() => userdata_to_dom!(value as Instance => dom::Ref),

View file

@ -21,6 +21,7 @@ impl DomValueExt for DomType {
Content => "Content", Content => "Content",
ContentId => "ContentId", ContentId => "ContentId",
Enum => "Enum", Enum => "Enum",
EnumItem => "EnumItem",
Faces => "Faces", Faces => "Faces",
Float32 => "Float32", Float32 => "Float32",
Float64 => "Float64", Float64 => "Float64",

View file

@ -1,7 +1,7 @@
use core::fmt; use core::fmt;
use mlua::prelude::*; use mlua::prelude::*;
use rbx_dom_weak::types::Enum as DomEnum; use rbx_dom_weak::types::EnumItem as DomEnumItem;
use super::{super::*, Enum}; use super::{super::*, Enum};
@ -100,8 +100,18 @@ impl PartialEq for EnumItem {
} }
} }
impl From<EnumItem> for DomEnum { impl From<EnumItem> for DomEnumItem {
fn from(v: EnumItem) -> Self { fn from(v: EnumItem) -> Self {
DomEnum::from_u32(v.value) DomEnumItem {
ty: v.parent.desc.name.to_string(),
value: v.value,
}
}
}
impl From<DomEnumItem> 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")
} }
} }

View file

@ -331,7 +331,7 @@ fn instance_property_set<'lua>(
if let Some(enum_name) = info.enum_name { if let Some(enum_name) = info.enum_name {
match LuaUserDataRef::<EnumItem>::from_lua(prop_value, lua) { match LuaUserDataRef::<EnumItem>::from_lua(prop_value, lua) {
Ok(given_enum) if given_enum.parent.desc.name == enum_name => { 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(())
} }
Ok(given_enum) => Err(LuaError::RuntimeError(format!( Ok(given_enum) => Err(LuaError::RuntimeError(format!(

View file

@ -16,6 +16,7 @@ local UDim2 = roblox.UDim2
local Vector2 = roblox.Vector2 local Vector2 = roblox.Vector2
local Vector3 = roblox.Vector3 local Vector3 = roblox.Vector3
local Instance = roblox.Instance local Instance = roblox.Instance
local Enum = roblox.Enum
local modelFile = fs.readFile("tests/roblox/rbx-test-files/models/attributes/binary.rbxm") local modelFile = fs.readFile("tests/roblox/rbx-test-files/models/attributes/binary.rbxm")
local model = roblox.deserializeModel(modelFile)[1] local model = roblox.deserializeModel(modelFile)[1]
@ -114,3 +115,12 @@ model.Parent = game
local placeFile = roblox.serializePlace(game) local placeFile = roblox.serializePlace(game)
fs.writeDir("bin/roblox") fs.writeDir("bin/roblox")
fs.writeFile("bin/roblox/attributes.rbxl", placeFile) 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)

View file

@ -33,6 +33,16 @@ part.Shape = Enum.PartType.Ball
assert(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 -- Properties that don't exist for a class should error
local meshPart = Instance.new("MeshPart") local meshPart = Instance.new("MeshPart")