diff --git a/Cargo.lock b/Cargo.lock index ce48f1b..3f46979 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1051,7 +1051,6 @@ name = "lune-roblox" version = "0.6.1" dependencies = [ "anyhow", - "base64 0.21.0", "glam", "lazy_static", "mlua", diff --git a/packages/lib-roblox/Cargo.toml b/packages/lib-roblox/Cargo.toml index 85a48c6..c39b444 100644 --- a/packages/lib-roblox/Cargo.toml +++ b/packages/lib-roblox/Cargo.toml @@ -18,7 +18,6 @@ path = "src/lib.rs" mlua.workspace = true lazy_static.workspace = true -base64 = "0.21" glam = "0.23" rand = "0.8" thiserror = "1.0" diff --git a/packages/lib-roblox/src/datatypes/conversion.rs b/packages/lib-roblox/src/datatypes/conversion.rs index 2e5016f..8d2a55b 100644 --- a/packages/lib-roblox/src/datatypes/conversion.rs +++ b/packages/lib-roblox/src/datatypes/conversion.rs @@ -39,9 +39,6 @@ pub(crate) trait DomValueToLua<'lua>: Sized { impl<'lua> DomValueToLua<'lua> for LuaValue<'lua> { fn dom_value_to_lua(lua: &'lua Lua, variant: &DomValue) -> DomConversionResult { - use base64::engine::general_purpose::STANDARD_NO_PAD; - use base64::engine::Engine as _; - use rbx_dom_weak::types as dom; match LuaAnyUserData::dom_value_to_lua(lua, variant) { @@ -53,13 +50,10 @@ impl<'lua> DomValueToLua<'lua> for LuaValue<'lua> { DomValue::Float64(n) => Ok(LuaValue::Number(*n)), DomValue::Float32(n) => Ok(LuaValue::Number(*n as f64)), DomValue::String(s) => Ok(LuaValue::String(lua.create_string(s)?)), + DomValue::BinaryString(s) => Ok(LuaValue::String(lua.create_string(&s)?)), DomValue::Content(s) => Ok(LuaValue::String( lua.create_string(AsRef::::as_ref(s))?, )), - DomValue::BinaryString(s) => { - let encoded = STANDARD_NO_PAD.encode(AsRef::<[u8]>::as_ref(s)); - Ok(LuaValue::String(lua.create_string(&encoded)?)) - } // NOTE: Some values are either optional or default and we should handle // that properly here since the userdata conversion above will always fail @@ -78,9 +72,6 @@ impl<'lua> LuaToDomValue<'lua> for LuaValue<'lua> { lua: &'lua Lua, variant_type: Option, ) -> DomConversionResult { - use base64::engine::general_purpose::STANDARD_NO_PAD; - use base64::engine::Engine as _; - use rbx_dom_weak::types as dom; if let Some(variant_type) = variant_type { @@ -100,12 +91,12 @@ impl<'lua> LuaToDomValue<'lua> for LuaValue<'lua> { (LuaValue::String(s), DomType::String) => { Ok(DomValue::String(s.to_str()?.to_string())) } + (LuaValue::String(s), DomType::BinaryString) => { + Ok(DomValue::BinaryString(s.as_ref().into())) + } (LuaValue::String(s), DomType::Content) => { Ok(DomValue::Content(s.to_str()?.to_string().into())) } - (LuaValue::String(s), DomType::BinaryString) => { - Ok(DomValue::BinaryString(STANDARD_NO_PAD.decode(s)?.into())) - } // NOTE: Some values are either optional or default and we // should handle that here before trying to convert as userdata diff --git a/packages/lib-roblox/src/datatypes/result.rs b/packages/lib-roblox/src/datatypes/result.rs index 5f43dd3..3ceb41e 100644 --- a/packages/lib-roblox/src/datatypes/result.rs +++ b/packages/lib-roblox/src/datatypes/result.rs @@ -72,12 +72,4 @@ impl From for DomConversionError { } } -impl From for DomConversionError { - fn from(value: base64::DecodeError) -> Self { - DomConversionError::External { - message: value.to_string(), - } - } -} - pub(crate) type DomConversionResult = Result; diff --git a/packages/lib/src/tests.rs b/packages/lib/src/tests.rs index 8180894..d6e9b80 100644 --- a/packages/lib/src/tests.rs +++ b/packages/lib/src/tests.rs @@ -120,6 +120,7 @@ create_tests! { roblox_files_read_place: "roblox/files/readPlaceFile", roblox_files_write_model: "roblox/files/writeModelFile", roblox_files_write_place: "roblox/files/writePlaceFile", + roblox_instance_attributes: "roblox/instance/attributes", roblox_instance_new: "roblox/instance/new", roblox_instance_properties: "roblox/instance/properties", } diff --git a/tests/roblox/instance/attributes.luau b/tests/roblox/instance/attributes.luau new file mode 100644 index 0000000..f373aa5 --- /dev/null +++ b/tests/roblox/instance/attributes.luau @@ -0,0 +1,67 @@ +local roblox = require("@lune/roblox") :: any +local BrickColor = roblox.BrickColor +local Color3 = roblox.Color3 +local ColorSequence = roblox.ColorSequence +local ColorSequenceKeypoint = roblox.ColorSequenceKeypoint +local NumberRange = roblox.NumberRange +local NumberSequence = roblox.NumberSequence +local NumberSequenceKeypoint = roblox.NumberSequenceKeypoint +local Rect = roblox.Rect +local UDim = roblox.UDim +local UDim2 = roblox.UDim2 +local Vector2 = roblox.Vector2 +local Vector3 = roblox.Vector3 +local CFrame = roblox.CFrame + +local model = roblox.readModelFile("tests/roblox/rbx-test-files/models/attributes/binary.rbxm")[1] + +model:SetAttribute("Foo", "Bar") +model:SetAttribute("CFrame", CFrame.identity) + +local ATTRS_ACTUAL = model:GetAttributes() +local ATTRS_EXPECTED: { [string]: any } = { + -- From the file + Boolean = true, + BrickColor = BrickColor.new("Really red"), + Color3 = Color3.fromRGB(162, 0, 255), + ColorSequence = ColorSequence.new({ + ColorSequenceKeypoint.new(0, Color3.new(1, 0, 0)), + ColorSequenceKeypoint.new(0.5, Color3.new(0, 1, 0)), + ColorSequenceKeypoint.new(1, Color3.new(0, 0, 1)), + }), + Number = 12345, + NumberRange = NumberRange.new(5, 10), + NumberSequence = NumberSequence.new({ + NumberSequenceKeypoint.new(0, 1), + NumberSequenceKeypoint.new(0.5, 0), + NumberSequenceKeypoint.new(1, 1), + }), + Rect = Rect.new(1, 2, 3, 4), + String = "Hello, world!", + UDim = UDim.new(0.5, 100), + UDim2 = UDim2.new(0.5, 10, 0.7, 30), + Vector2 = Vector2.new(10, 50), + Vector3 = Vector3.new(1, 2, 3), + Infinity = math.huge, + NaN = 0 / 0, + -- Extras we set + Foo = "Bar", + CFrame = CFrame.identity, +} + +for name, value in ATTRS_EXPECTED do + local actual = ATTRS_ACTUAL[name] + if actual ~= value then + if value ~= value and actual ~= actual then + continue -- NaN + end + error( + string.format( + "Expected attribute '%s' to have value '%s', got value '%s'", + name, + tostring(value), + tostring(actual) + ) + ) + end +end