Improve codegen of Font roblox datatype enums some more

This commit is contained in:
Filip Tibell 2023-03-18 08:39:46 +01:00
parent b7d0481a83
commit cc8f6ec843
No known key found for this signature in database
2 changed files with 215 additions and 72 deletions

View file

@ -12,13 +12,13 @@ pub(crate) enum <<ENUM_NAME>> {
}
impl <<ENUM_NAME>> {
pub fn as_<<NUMBER_TYPE>>(&self) -> <<NUMBER_TYPE>> {
pub(crate) fn as_<<NUMBER_TYPE>>(&self) -> <<NUMBER_TYPE>> {
match self {
<<ENUM_TO_NUMBERS>>
}
}
pub fn from_<<NUMBER_TYPE>>(n: <<NUMBER_TYPE>>) -> Option<Self> {
pub(crate) fn from_<<NUMBER_TYPE>>(n: <<NUMBER_TYPE>>) -> Option<Self> {
match n {
<<NUMBERS_TO_ENUM>>
_ => None,
@ -26,6 +26,12 @@ impl <<ENUM_NAME>> {
}
}
impl Default for <<ENUM_NAME>> {
fn default() -> Self {
Self::<<DEFAULT_NAME>>
}
}
impl std::str::FromStr for <<ENUM_NAME>> {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
@ -48,12 +54,59 @@ impl std::fmt::Display for <<ENUM_NAME>> {
}
}
impl<'lua> FromLua<'lua> for <<ENUM_NAME>> {
fn from_lua(lua_value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
let mut message = None;
if let LuaValue::UserData(ud) = &lua_value {
let value = ud.borrow::<EnumItem>()?;
if value.parent.desc.name == "<<ENUM_NAME>>" {
if let Ok(value) = <<ENUM_NAME>>::from_str(&value.name) {
return Ok(value);
} else {
message = Some(format!(
"Found unknown Enum.<<ENUM_NAME>> value '{}'",
value.name
));
}
} else {
message = Some(format!(
"Expected Enum.<<ENUM_NAME>>, got Enum.{}",
value.parent.desc.name
));
}
}
Err(LuaError::FromLuaConversionError {
from: lua_value.type_name(),
to: "Enum.<<ENUM_NAME>>",
message,
})
}
}
impl<'lua> ToLua<'lua> for <<ENUM_NAME>> {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
match EnumItem::from_enum_name_and_name("<<ENUM_NAME>>", self.to_string()) {
Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)),
None => Err(LuaError::ToLuaConversionError {
from: "<<ENUM_NAME>>",
to: "EnumItem",
message: Some(format!("Found unknown Enum.<<ENUM_NAME>> value '{}'", self)),
}),
}
}
}
]]
-- FontWeight enum and implementation
local function makeRustEnum(enum, numType: string)
local name = string.gsub(tostring(enum), "^Enum.", "")
local function makeRustEnum(enum, default, numType: string)
local name = tostring(enum)
name = string.gsub(name, "^Enum.", "")
local defaultName = tostring(default)
defaultName = string.gsub(defaultName, "^Enum.", "")
defaultName = string.gsub(defaultName, "^" .. name .. ".", "")
local enumNames = ""
local enumToNumbers = ""
@ -71,6 +124,7 @@ local function makeRustEnum(enum, numType: string)
local mappings: { [string]: string } = {
["<<ENUM_NAME>>"] = name,
["<<DEFAULT_NAME>>"] = defaultName,
["<<NUMBER_TYPE>>"] = numType,
["<<ENUM_NAMES>>"] = enumNames,
["<<ENUM_TO_NUMBERS>>"] = enumToNumbers,
@ -91,10 +145,10 @@ local function makeRustEnum(enum, numType: string)
return result
end
contents ..= makeRustEnum(Enum.FontWeight, "u16")
contents ..= makeRustEnum(Enum.FontWeight, Enum.FontWeight.Regular, "u16")
contents ..= "\n"
contents ..= makeRustEnum(Enum.FontStyle, "u8")
contents ..= makeRustEnum(Enum.FontStyle, Enum.FontStyle.Normal, "u8")
contents ..= "\n"
-- Font constant map from enum to font data

View file

@ -21,7 +21,7 @@ pub struct Font {
}
impl Font {
pub(crate) fn from_enum(material_enum_item: &EnumItem) -> Option<Font> {
pub(crate) fn from_enum_item(material_enum_item: &EnumItem) -> Option<Font> {
FONT_ENUM_MAP
.iter()
.find(|props| props.0 == material_enum_item.name && props.1.is_some())
@ -34,11 +34,23 @@ impl Font {
}
pub(crate) fn make_table(lua: &Lua, datatype_table: &LuaTable) -> LuaResult<()> {
datatype_table.set(
"new",
lua.create_function(
|_, (family, weight, style): (String, Option<FontWeight>, Option<FontStyle>)| {
Ok(Font {
family,
weight: weight.unwrap_or_default(),
style: style.unwrap_or_default(),
})
},
)?,
)?;
datatype_table.set(
"fromEnum",
lua.create_function(|_, value: EnumItem| {
if value.parent.desc.name == "Font" {
match Font::from_enum(&value) {
match Font::from_enum_item(&value) {
Some(props) => Ok(props),
None => Err(LuaError::RuntimeError(format!(
"Found unknown Font '{}'",
@ -53,9 +65,30 @@ impl Font {
}
})?,
)?;
// TODO: Add fromName and fromId constructors
// TODO: Add "new" constructor
Ok(())
datatype_table.set(
"fromName",
lua.create_function(
|_, (file, weight, style): (String, Option<FontWeight>, Option<FontStyle>)| {
Ok(Font {
family: format!("rbxasset://fonts/families/{}.json", file),
weight: weight.unwrap_or_default(),
style: style.unwrap_or_default(),
})
},
)?,
)?;
datatype_table.set(
"fromId",
lua.create_function(
|_, (id, weight, style): (i32, Option<FontWeight>, Option<FontStyle>)| {
Ok(Font {
family: format!("rbxassetid://{}", id),
weight: weight.unwrap_or_default(),
style: style.unwrap_or_default(),
})
},
)?,
)
}
}
@ -63,57 +96,17 @@ impl LuaUserData for Font {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
// Getters
fields.add_field_method_get("Family", |_, this| Ok(this.family.clone()));
fields.add_field_method_get("Weight", |_, this| {
Ok(EnumItem::from_enum_name_and_name(
"FontWeight",
this.weight.to_string(),
))
});
fields.add_field_method_get("Style", |_, this| {
Ok(EnumItem::from_enum_name_and_name(
"FontStyle",
this.style.to_string(),
))
});
fields.add_field_method_get("Bold", |_, this| Ok(this.weight.clone().as_u16() >= 600));
fields.add_field_method_get("Weight", |_, this| Ok(this.weight));
fields.add_field_method_get("Style", |_, this| Ok(this.style));
fields.add_field_method_get("Bold", |_, this| Ok(this.weight.as_u16() >= 600));
// Setters
fields.add_field_method_set("Weight", |_, this, value: EnumItem| {
if value.parent.desc.name == "FontWeight" {
match FontWeight::from_str(&value.name) {
Ok(weight) => {
this.weight = weight;
fields.add_field_method_set("Weight", |_, this, value: FontWeight| {
this.weight = value;
Ok(())
}
Err(e) => Err(LuaError::RuntimeError(format!(
"Failed to set value to FontWeight '{}' - {}",
value.name, e
))),
}
} else {
Err(LuaError::RuntimeError(format!(
"Expected value to be a FontWeight, got {}",
value.parent.desc.name
)))
}
});
fields.add_field_method_set("Style", |_, this, value: EnumItem| {
if value.parent.desc.name == "FontStyle" {
match FontStyle::from_str(&value.name) {
Ok(style) => {
this.style = style;
fields.add_field_method_set("Style", |_, this, value: FontStyle| {
this.style = value;
Ok(())
}
Err(e) => Err(LuaError::RuntimeError(format!(
"Failed to set value to FontStyle '{}' - {}",
value.name, e
))),
}
} else {
Err(LuaError::RuntimeError(format!(
"Expected value to be a FontStyle, got {}",
value.parent.desc.name
)))
}
});
fields.add_field_method_set("Bold", |_, this, value: bool| {
if value {
@ -206,7 +199,7 @@ pub(crate) enum FontWeight {
}
impl FontWeight {
pub fn as_u16(&self) -> u16 {
pub(crate) fn as_u16(&self) -> u16 {
match self {
Self::Thin => 100,
Self::ExtraLight => 200,
@ -220,7 +213,7 @@ impl FontWeight {
}
}
pub fn from_u16(n: u16) -> Option<Self> {
pub(crate) fn from_u16(n: u16) -> Option<Self> {
match n {
100 => Some(Self::Thin),
200 => Some(Self::ExtraLight),
@ -236,6 +229,12 @@ impl FontWeight {
}
}
impl Default for FontWeight {
fn default() -> Self {
Self::Regular
}
}
impl std::str::FromStr for FontWeight {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
@ -274,6 +273,48 @@ impl std::fmt::Display for FontWeight {
}
}
impl<'lua> FromLua<'lua> for FontWeight {
fn from_lua(lua_value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
let mut message = None;
if let LuaValue::UserData(ud) = &lua_value {
let value = ud.borrow::<EnumItem>()?;
if value.parent.desc.name == "FontWeight" {
if let Ok(value) = FontWeight::from_str(&value.name) {
return Ok(value);
} else {
message = Some(format!(
"Found unknown Enum.FontWeight value '{}'",
value.name
));
}
} else {
message = Some(format!(
"Expected Enum.FontWeight, got Enum.{}",
value.parent.desc.name
));
}
}
Err(LuaError::FromLuaConversionError {
from: lua_value.type_name(),
to: "Enum.FontWeight",
message,
})
}
}
impl<'lua> ToLua<'lua> for FontWeight {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
match EnumItem::from_enum_name_and_name("FontWeight", self.to_string()) {
Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)),
None => Err(LuaError::ToLuaConversionError {
from: "FontWeight",
to: "EnumItem",
message: Some(format!("Found unknown Enum.FontWeight value '{}'", self)),
}),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) enum FontStyle {
Normal,
@ -281,14 +322,14 @@ pub(crate) enum FontStyle {
}
impl FontStyle {
pub fn as_u8(&self) -> u8 {
pub(crate) fn as_u8(&self) -> u8 {
match self {
Self::Normal => 0,
Self::Italic => 1,
}
}
pub fn from_u8(n: u8) -> Option<Self> {
pub(crate) fn from_u8(n: u8) -> Option<Self> {
match n {
0 => Some(Self::Normal),
1 => Some(Self::Italic),
@ -297,6 +338,12 @@ impl FontStyle {
}
}
impl Default for FontStyle {
fn default() -> Self {
Self::Normal
}
}
impl std::str::FromStr for FontStyle {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
@ -321,6 +368,48 @@ impl std::fmt::Display for FontStyle {
}
}
impl<'lua> FromLua<'lua> for FontStyle {
fn from_lua(lua_value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
let mut message = None;
if let LuaValue::UserData(ud) = &lua_value {
let value = ud.borrow::<EnumItem>()?;
if value.parent.desc.name == "FontStyle" {
if let Ok(value) = FontStyle::from_str(&value.name) {
return Ok(value);
} else {
message = Some(format!(
"Found unknown Enum.FontStyle value '{}'",
value.name
));
}
} else {
message = Some(format!(
"Expected Enum.FontStyle, got Enum.{}",
value.parent.desc.name
));
}
}
Err(LuaError::FromLuaConversionError {
from: lua_value.type_name(),
to: "Enum.FontStyle",
message,
})
}
}
impl<'lua> ToLua<'lua> for FontStyle {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
match EnumItem::from_enum_name_and_name("FontStyle", self.to_string()) {
Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)),
None => Err(LuaError::ToLuaConversionError {
from: "FontStyle",
to: "EnumItem",
message: Some(format!("Found unknown Enum.FontStyle value '{}'", self)),
}),
}
}
}
#[rustfmt::skip]
const FONT_ENUM_MAP: &[(&str, Option<FontData>)] = &[
("Legacy", Some(("rbxasset://fonts/families/LegacyArial.json", FontWeight::Regular, FontStyle::Normal))),