Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement enum attributes #470

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This document describes the Attribute binary format. In this format there is no
- [Vector2](#vector2)
- [Vector3](#vector3)
- [CFrame](#cframe)
- [EnumItem](#EnumItem)
- [EnumItem](#enumitem)
- [NumberSequence](#numbersequence)
- [ColorSequence](#colorsequence)
- [NumberRange](#numberrange)
Expand All @@ -27,7 +27,7 @@ This document describes the Attribute binary format. In this format there is no

## Document Conventions

This document assumes a basic understanding of Rust's convention for numeric types. For example:
This document assumes a basic understanding of Rust's convention for numeric types. For example:

- `u32` is an unsigned 32-bit integer
- `f32` is a 32-bit floating point
Expand Down Expand Up @@ -189,7 +189,7 @@ Demonstrating the axis-aligned rotation matrix case, a `CFrame` with the value `
### EnumItem
**Type ID `0x15`**

The `EnumItem` type is composed of two parts:
The `EnumItem` type is composed of two parts:

| Field Name | Format | Value |
|:-----------|:--------------------|:-------------------------------------------------------|
Expand Down
1 change: 1 addition & 0 deletions rbx_binary/src/tests/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,5 @@ binary_tests! {
folder_with_font_attribute,
number_values_with_security_capabilities,
lighting_with_int32_attribute,
folder_with_enum_attribute,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
source: rbx_binary/src/tests/util.rs
expression: decoded_viewed
---
- referent: referent-0
name: Folder
class: Folder
properties:
Attributes:
Attributes:
AnEnumValue:
EnumItem:
type: Material
value: 512
Capabilities:
SecurityCapabilities: 0
Sandboxed:
Bool: false
SourceAssetId:
Int64: -1
Tags:
Tags: []
children: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
source: rbx_binary/src/tests/util.rs
expression: text_roundtrip
---
num_types: 1
num_instances: 1
chunks:
- Inst:
type_id: 0
type_name: Folder
object_format: 0
referents:
- 0
- Prop:
type_id: 0
prop_name: AttributesSerialize
prop_type: String
values:
- "\u0001\u0000\u0000\u0000\u000b\u0000\u0000\u0000AnEnumValue\u0015\b\u0000\u0000\u0000Material\u0000\u0002\u0000\u0000"
- Prop:
type_id: 0
prop_name: Capabilities
prop_type: SecurityCapabilities
values:
- 0
- Prop:
type_id: 0
prop_name: Name
prop_type: String
values:
- Folder
- Prop:
type_id: 0
prop_name: DefinesCapabilities
prop_type: Bool
values:
- false
- Prop:
type_id: 0
prop_name: SourceAssetId
prop_type: Int64
values:
- -1
- Prop:
type_id: 0
prop_name: Tags
prop_type: String
values:
- ""
- Prnt:
version: 0
links:
- - 0
- -1
- End
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
source: rbx_binary/src/tests/util.rs
expression: text_decoded
---
num_types: 1
num_instances: 1
chunks:
- Meta:
entries:
- - ExplicitAutoJoints
- "true"
- Inst:
type_id: 0
type_name: Folder
object_format: 0
referents:
- 0
- Prop:
type_id: 0
prop_name: AttributesSerialize
prop_type: String
values:
- "\u0001\u0000\u0000\u0000\u000b\u0000\u0000\u0000AnEnumValue\u0015\b\u0000\u0000\u0000Material\u0000\u0002\u0000\u0000"
- Prop:
type_id: 0
prop_name: Capabilities
prop_type: SecurityCapabilities
values:
- 0
- Prop:
type_id: 0
prop_name: DefinesCapabilities
prop_type: Bool
values:
- false
- Prop:
type_id: 0
prop_name: Name
prop_type: String
values:
- Folder
- Prop:
type_id: 0
prop_name: SourceAssetId
prop_type: Int64
values:
- -1
- Prop:
type_id: 0
prop_name: Tags
prop_type: String
values:
- ""
- Prnt:
version: 0
links:
- - 0
- -1
- End
18 changes: 18 additions & 0 deletions rbx_dom_lua/src/EncodedValue.lua
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,24 @@ types = {
end,
},

EnumItem = {
fromPod = function(pod)
local enum = Enum[pod.type]

-- If the given EnumItem value is not valid for this Enum, then
-- that's pretty weird, but we'll just return the first one in the
-- list instead
return enum:FromValue(pod.value) or enum:GetEnumItems()[1]
end,
kennethloeffler marked this conversation as resolved.
Show resolved Hide resolved

toPod = function(roblox)
return {
type = tostring(roblox.EnumType),
value = roblox.Value,
}
end,
},

Faces = {
fromPod = function(pod)
local faces = {}
Expand Down
9 changes: 9 additions & 0 deletions rbx_dom_lua/src/allValues.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@
},
"ty": "Enum"
},
"EnumItem": {
"value": {
"EnumItem": {
"type": "Material",
"value": 256
}
},
"ty": "EnumItem"
},
"Faces": {
"value": {
"Faces": [
Expand Down
3 changes: 2 additions & 1 deletion rbx_dom_lua/test
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/sh

cargo run --bin rbx_reflector values ./src/allValues.json
rojo build test-place.project.json -o TestPlace.rbxlx
run-in-roblox --script run-tests.lua --place TestPlace.rbxlx
run-in-roblox --script run-tests.lua --place TestPlace.rbxlx
16 changes: 12 additions & 4 deletions rbx_reflector/src/cli/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use anyhow::bail;
use clap::Parser;
use rbx_types::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, Faces, Font, MaterialColors,
Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint, PhysicalProperties, Ray, Rect,
Region3int16, Tags, TerrainMaterials, UDim, UDim2, Variant, VariantType, Vector2, Vector2int16,
Vector3, Vector3int16,
ColorSequenceKeypoint, Content, CustomPhysicalProperties, Enum, EnumItem, Faces, Font,
MaterialColors, Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint,
PhysicalProperties, Ray, Rect, Region3int16, Tags, TerrainMaterials, UDim, UDim2, Variant,
VariantType, Vector2, Vector2int16, Vector3, Vector3int16,
};
use serde::Serialize;

Expand Down Expand Up @@ -80,6 +80,14 @@ impl ValuesSubcommand {
);
values.insert("Content", Content::from("rbxassetid://12345").into());
values.insert("Enum", Enum::from_u32(1234).into());
values.insert(
"EnumItem",
EnumItem {
ty: "Material".into(),
value: 256,
}
.into(),
);
values.insert("Faces", Faces::all().into());
values.insert("Float32", 15.0f32.into());
values.insert("Float64", 15123.0f64.into());
Expand Down
3 changes: 3 additions & 0 deletions rbx_types/src/attributes/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ pub(crate) enum AttributeError {
#[error(transparent)]
Io(#[from] std::io::Error),

#[error(transparent)]
Utf8(#[from] std::string::FromUtf8Error),

#[error(transparent)]
BadAttributeValue(#[from] crate::Error),

Expand Down
13 changes: 12 additions & 1 deletion rbx_types/src/attributes/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
};

use crate::{
BinaryString, BrickColor, CFrame, Color3, ColorSequence, ColorSequenceKeypoint, Font,
BinaryString, BrickColor, CFrame, Color3, ColorSequence, ColorSequenceKeypoint, EnumItem, Font,
FontStyle, FontWeight, Matrix3, NumberRange, NumberSequence, NumberSequenceKeypoint, Rect,
UDim, UDim2, Variant, VariantType, Vector2, Vector3,
};
Expand Down Expand Up @@ -202,6 +202,17 @@ pub(crate) fn read_attributes<R: Read>(
}
.into(),

VariantType::EnumItem => {
let enum_type = read_string(&mut value)?;
let value = read_u32(&mut value)?;

EnumItem {
ty: String::from_utf8(enum_type)?,
value,
}
}
.into(),

other => return Err(AttributeError::UnsupportedVariantType(other)),
};

Expand Down
2 changes: 1 addition & 1 deletion rbx_types/src/attributes/type_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type_ids! {
// ??? => 0x12,
// ??? => 0x13,
CFrame => 0x14,
// ??? => 0x15,
EnumItem => 0x15,
// ??? => 0x16,
NumberSequence => 0x17,
// ??? => 0x18,
Expand Down
4 changes: 4 additions & 0 deletions rbx_types/src/attributes/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ pub(crate) fn write_attributes<W: Write>(
font.cached_face_id.as_deref().unwrap_or_default(),
)?;
}
Variant::EnumItem(enum_item) => {
write_string(&mut writer, &enum_item.ty)?;
write_u32(&mut writer, enum_item.value)?;
}

other_variant => unreachable!("variant {:?} was not implemented", other_variant),
}
Expand Down
35 changes: 33 additions & 2 deletions rbx_types/src/basic_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use thiserror::Error;

use crate::Error;

/// Represents any Roblox enum value.
/// Represents any Roblox EnumItem.
///
/// Roblox enums are not strongly typed, so the meaning of a value depends on
/// where they're assigned.
///
/// A list of all enums and their values are available [on the Roblox Developer
/// Hub](https://developer.roblox.com/en-us/api-reference/enum).
/// Hub](https://create.roblox.com/docs/reference/engine/enums).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
Expand All @@ -29,6 +29,26 @@ impl Enum {
}
}

/// Represents a specific Roblox EnumItem.
///
/// A list of all enums and their values are available [on the Roblox Developer
/// Hub](https://create.roblox.com/docs/reference/engine/enums).
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize,))]
pub struct EnumItem {
#[serde(rename = "type")]
pub ty: String,
pub value: u32,
}

impl From<EnumItem> for Enum {
fn from(enum_item: EnumItem) -> Self {
Self {
value: enum_item.value,
}
}
}

/// The standard 2D vector type used in Roblox.
///
/// ## See Also
Expand Down Expand Up @@ -718,4 +738,15 @@ mod serde_test {
"[[1.0,2.0,3.0],[4.0,5.0,6.0],[7.0,8.0,9.0]]",
);
}

#[test]
fn tagged_enum_json() {
test_ser(
EnumItem {
ty: "PlayTag".to_string(),
value: 3,
},
r#"{"type":"PlayTag","value":3}"#,
);
}
}
7 changes: 4 additions & 3 deletions rbx_types/src/variant.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{
Attributes, Axes, BinaryString, BrickColor, CFrame, Color3, Color3uint8, ColorSequence,
Content, Enum, Faces, Font, MaterialColors, NumberRange, NumberSequence, PhysicalProperties,
Ray, Rect, Ref, Region3, Region3int16, SecurityCapabilities, SharedString, Tags, UDim, UDim2,
UniqueId, Vector2, Vector2int16, Vector3, Vector3int16,
Content, Enum, EnumItem, Faces, Font, MaterialColors, NumberRange, NumberSequence,
PhysicalProperties, Ray, Rect, Ref, Region3, Region3int16, SecurityCapabilities, SharedString,
Tags, UDim, UDim2, UniqueId, Vector2, Vector2int16, Vector3, Vector3int16,
};

/// Reduces boilerplate from listing different values of Variant by wrapping
Expand Down Expand Up @@ -129,6 +129,7 @@ make_variant! {
UniqueId(UniqueId),
MaterialColors(MaterialColors),
SecurityCapabilities(SecurityCapabilities),
EnumItem(EnumItem),
}

impl From<&'_ str> for Variant {
Expand Down
1 change: 1 addition & 0 deletions rbx_xml/src/tests/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,5 @@ model_tests! {
folder_with_font_attribute,
number_values_with_security_capabilities,
lighting_with_int32_attribute,
folder_with_enum_attribute,
}
Loading