Skip to content

Commit

Permalink
Merge branch 'master' into implement-enum-attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethloeffler committed Nov 1, 2024
2 parents 28a187c + 8ecd2fa commit 47335ad
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 40 deletions.
7 changes: 0 additions & 7 deletions rbx_binary/src/deserializer/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,4 @@ pub(crate) enum InnerError {
expected_type_id: u8,
actual_type_id: u8,
},

#[error("Failed to deserialize {class_name}.{prop_name} because {source}")]
BadPropertyValue {
source: rbx_dom_weak::types::Error,
prop_name: String,
class_name: String,
},
}
36 changes: 26 additions & 10 deletions rbx_binary/src/deserializer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,11 +481,19 @@ This may cause unexpected or broken behavior in your final results if you rely o
add_property(instance, &property, value.into());
}
Err(err) => {
return Err(InnerError::BadPropertyValue {
source: err,
class_name: type_info.type_name.to_string(),
prop_name,
})
log::warn!(
"Failed to parse Attributes on {} because {:?}; falling back to BinaryString.
rbx-dom may require changes to fully support this property. Please open an issue at https://github.com/rojo-rbx/rbx-dom/issues and show this warning.",
type_info.type_name,
err
);

add_property(
instance,
&property,
BinaryString::from(buffer).into(),
);
}
}
}
Expand All @@ -497,11 +505,19 @@ This may cause unexpected or broken behavior in your final results if you rely o
match MaterialColors::decode(&buffer) {
Ok(value) => add_property(instance, &property, value.into()),
Err(err) => {
return Err(InnerError::BadPropertyValue {
source: err,
class_name: type_info.type_name.to_string(),
prop_name,
})
log::warn!(
"Failed to parse MaterialColors on {} because {:?}; falling back to BinaryString.
rbx-dom may require changes to fully support this property. Please open an issue at https://github.com/rojo-rbx/rbx-dom/issues and show this warning.",
type_info.type_name,
err
);

add_property(
instance,
&property,
BinaryString::from(buffer).into(),
);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions rbx_dom_lua/src/Error.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Error.Kind = {
UnknownProperty = "UnknownProperty",
PropertyNotReadable = "PropertyNotReadable",
PropertyNotWritable = "PropertyNotWritable",
CannotParseBinaryString = "CannotParseBinaryString",
Roblox = "Roblox",
}

Expand Down
11 changes: 11 additions & 0 deletions rbx_dom_lua/src/customProperties.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
local CollectionService = game:GetService("CollectionService")
local ScriptEditorService = game:GetService("ScriptEditorService")

local Error = require(script.Parent.Error)

--- A list of `Enum.Material` values that are used for Terrain.MaterialColors
local TERRAIN_MATERIAL_COLORS = {
Enum.Material.Grass,
Expand Down Expand Up @@ -51,6 +53,10 @@ return {
return true, instance:GetAttributes()
end,
write = function(instance, _, value)
if typeof(value) ~= "table" then
return false, Error.new(Error.Kind.CannotParseBinaryString)
end

local existing = instance:GetAttributes()
local didAllWritesSucceed = true

Expand Down Expand Up @@ -160,9 +166,14 @@ return {
return true, colors
end,
write = function(instance: Terrain, _, value: { [Enum.Material]: Color3 })
if typeof(value) ~= "table" then
return false, Error.new(Error.Kind.CannotParseBinaryString)
end

for material, color in value do
instance:SetMaterialColor(material, color)
end

return true
end,
},
Expand Down
20 changes: 15 additions & 5 deletions rbx_reflector/src/cli/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,18 @@ fn apply_dump(database: &mut ReflectionDatabase, dump: &Dump) -> anyhow::Result<
// are usually only present in Roblox Studio
// settings files. They are not used otherwise and
// can safely be ignored.
(None, PropertyKind::Canonical {
serialization: PropertySerialization::Serializes
}) if type_name != "QDir" && type_name != "QFont" => bail!(
(
None,
PropertyKind::Canonical {
serialization: PropertySerialization::Serializes,
},
) if type_name != "QDir" && type_name != "QFont" => {
log::warn!(
"Property {}.{} serializes, but its data type ({}) is unimplemented",
dump_class.name, dump_property.name, type_name
),
);
continue;
}

// The data type does not have a corresponding a
// VariantType, and it does not serialize (with QDir
Expand All @@ -241,7 +247,11 @@ fn apply_dump(database: &mut ReflectionDatabase, dump: &Dump) -> anyhow::Result<
// need to know about data types that are never
// serialized.
(None, _) => {
ignored_properties.push((&dump_class.name, &dump_property.name, type_name));
ignored_properties.push((
&dump_class.name,
&dump_property.name,
type_name,
));
continue;
}
}
Expand Down
60 changes: 44 additions & 16 deletions rbx_xml/src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,36 @@
use std::borrow::{Borrow, Cow};
use std::convert::TryInto;

use rbx_dom_weak::types::{
Attributes, BrickColor, Color3uint8, Enum, MaterialColors, Tags, Variant, VariantType,
use rbx_dom_weak::types::Enum;
use rbx_dom_weak::{
types::{Attributes, BrickColor, Color3uint8, MaterialColors, Tags, Variant, VariantType},
Ustr,
};

pub trait ConvertVariant: Clone + Sized {
fn try_convert(self, target_type: VariantType) -> Result<Self, String> {
Self::try_convert_cow(Cow::Owned(self), target_type).map(|value| value.into_owned())
fn try_convert(self, class_name: Ustr, target_type: VariantType) -> Result<Self, String> {
Self::try_convert_cow(class_name, Cow::Owned(self), target_type)
.map(|value| value.into_owned())
}

fn try_convert_ref(&self, target_type: VariantType) -> Result<Cow<'_, Self>, String> {
Self::try_convert_cow(Cow::Borrowed(self), target_type)
fn try_convert_ref(
&self,
class_name: Ustr,
target_type: VariantType,
) -> Result<Cow<'_, Self>, String> {
Self::try_convert_cow(class_name, Cow::Borrowed(self), target_type)
}

fn try_convert_cow(
class_name: Ustr,
value: Cow<'_, Self>,
target_type: VariantType,
) -> Result<Cow<'_, Self>, String>;
}

impl ConvertVariant for Variant {
fn try_convert_cow(
class_name: Ustr,
value: Cow<'_, Self>,
target_type: VariantType,
) -> Result<Cow<'_, Self>, String> {
Expand Down Expand Up @@ -57,18 +66,37 @@ impl ConvertVariant for Variant {
)),
(Variant::BinaryString(value), VariantType::Attributes) => {
let bytes: &[u8] = value.as_ref();
match Attributes::from_reader(bytes) {
Ok(attributes) => Ok(Cow::Owned(attributes.into())),
Err(err) => {
log::warn!(
"Failed to parse Attributes on {} because {:?}; falling back to BinaryString.
Ok(Cow::Owned(
Attributes::from_reader(bytes)
.map_err(|_| "Unknown or invalid Attributes")?
.into(),
))
rbx-dom may require changes to fully support this property. Please open an issue at https://github.com/rojo-rbx/rbx-dom/issues and show this warning.",
class_name,
err
);

Ok(Cow::Owned(value.clone().into()))
}
}
}
(Variant::BinaryString(value), VariantType::MaterialColors) => {
match MaterialColors::decode(value.as_ref()) {
Ok(material_colors) => Ok(Cow::Owned(material_colors.into())),
Err(err) => {
log::warn!(
"Failed to parse MaterialColors on {} because {:?}; falling back to BinaryString.
rbx-dom may require changes to fully support this property. Please open an issue at https://github.com/rojo-rbx/rbx-dom/issues and show this warning.",
class_name,
err
);

Ok(Cow::Owned(value.clone().into()))
}
}
}
(Variant::BinaryString(value), VariantType::MaterialColors) => Ok(Cow::Owned(
MaterialColors::decode(value.as_ref())
.map_err(|_| "invalid MaterialColors value")?
.into(),
)),
(Variant::EnumItem(enum_item), VariantType::Enum) => {
Ok(Cow::Owned(Enum::from_u32(enum_item.value).into()))
}
Expand Down
2 changes: 1 addition & 1 deletion rbx_xml/src/deserializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ fn deserialize_properties<R: Read>(
};
log::trace!("property's read type: {xml_ty:?}, canonical type: {expected_type:?}");

let value = match value.try_convert(expected_type) {
let value = match value.try_convert(class_name, expected_type) {
Ok(value) => value,

// The property descriptor disagreed, and there was no
Expand Down
2 changes: 1 addition & 1 deletion rbx_xml/src/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ fn serialize_instance<'dom, W: Write>(

let mut serialized_name = serialized_descriptor.name.as_ref();

let mut converted_value = match value.try_convert_ref(data_type) {
let mut converted_value = match value.try_convert_ref(instance.class, data_type) {
Ok(value) => value,
Err(message) => {
return Err(
Expand Down

0 comments on commit 47335ad

Please sign in to comment.