Clean up conversion traits to make roblox datatypes easier to implement

This commit is contained in:
Filip Tibell 2023-03-11 19:25:48 +01:00
parent 89aaf40fdb
commit b1a3495a14
No known key found for this signature in database
8 changed files with 82 additions and 283 deletions

View file

@ -6,42 +6,35 @@ use crate::datatypes::extension::RbxVariantExt;
use super::*;
pub(crate) trait ToRbxVariant {
fn to_rbx_variant(
pub(crate) trait LuaToRbxVariant<'lua> {
fn lua_to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
lua: &'lua Lua,
variant_type: RbxVariantType,
) -> DatatypeConversionResult<RbxVariant>;
}
pub(crate) trait FromRbxVariant: Sized {
fn from_rbx_variant(variant: &RbxVariant) -> DatatypeConversionResult<Self>;
}
pub(crate) trait FromRbxVariantLua<'lua>: Sized {
fn from_rbx_variant_lua(variant: &RbxVariant, lua: &'lua Lua)
-> DatatypeConversionResult<Self>;
pub(crate) trait RbxVariantToLua<'lua>: Sized {
fn rbx_variant_to_lua(lua: &'lua Lua, variant: &RbxVariant) -> DatatypeConversionResult<Self>;
}
/*
Blanket trait implementations for converting between LuaValue and rbx_dom Variant values
These should be considered stable and one, already containing all of the primitive types
These should be considered stable and done, already containing all of the known primitives
See bottom of module for implementations between our custom datatypes and lua userdata
*/
impl<'lua> FromRbxVariantLua<'lua> for LuaValue<'lua> {
fn from_rbx_variant_lua(
variant: &RbxVariant,
lua: &'lua Lua,
) -> DatatypeConversionResult<Self> {
impl<'lua> RbxVariantToLua<'lua> for LuaValue<'lua> {
fn rbx_variant_to_lua(lua: &'lua Lua, variant: &RbxVariant) -> DatatypeConversionResult<Self> {
use base64::engine::general_purpose::STANDARD_NO_PAD;
use base64::engine::Engine as _;
use RbxVariant as Rbx;
match LuaAnyUserData::from_rbx_variant_lua(variant, lua) {
match LuaAnyUserData::rbx_variant_to_lua(lua, variant) {
Ok(value) => Ok(LuaValue::UserData(value)),
Err(e) => match variant {
Rbx::Bool(b) => Ok(LuaValue::Boolean(*b)),
@ -63,56 +56,44 @@ impl<'lua> FromRbxVariantLua<'lua> for LuaValue<'lua> {
}
}
impl<'lua> ToRbxVariant for LuaValue<'lua> {
fn to_rbx_variant(
impl<'lua> LuaToRbxVariant<'lua> for LuaValue<'lua> {
fn lua_to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
lua: &'lua Lua,
variant_type: RbxVariantType,
) -> DatatypeConversionResult<RbxVariant> {
use base64::engine::general_purpose::STANDARD_NO_PAD;
use base64::engine::Engine as _;
use RbxVariantType as Rbx;
if let Some(desired_type) = desired_type {
match (self, desired_type) {
(LuaValue::Boolean(b), Rbx::Bool) => Ok(RbxVariant::Bool(*b)),
(LuaValue::Integer(i), Rbx::Int64) => Ok(RbxVariant::Int64(*i as i64)),
(LuaValue::Integer(i), Rbx::Int32) => Ok(RbxVariant::Int32(*i)),
(LuaValue::Integer(i), Rbx::Float64) => Ok(RbxVariant::Float64(*i as f64)),
(LuaValue::Integer(i), Rbx::Float32) => Ok(RbxVariant::Float32(*i as f32)),
(LuaValue::Number(n), Rbx::Int64) => Ok(RbxVariant::Int64(*n as i64)),
(LuaValue::Number(n), Rbx::Int32) => Ok(RbxVariant::Int32(*n as i32)),
(LuaValue::Number(n), Rbx::Float64) => Ok(RbxVariant::Float64(*n)),
(LuaValue::Number(n), Rbx::Float32) => Ok(RbxVariant::Float32(*n as f32)),
(LuaValue::String(s), Rbx::String) => {
Ok(RbxVariant::String(s.to_str()?.to_string()))
}
(LuaValue::String(s), Rbx::Content) => {
Ok(RbxVariant::Content(s.to_str()?.to_string().into()))
}
(LuaValue::String(s), Rbx::BinaryString) => {
Ok(RbxVariant::BinaryString(STANDARD_NO_PAD.decode(s)?.into()))
}
(LuaValue::UserData(u), d) => u.to_rbx_variant(Some(d)),
(v, d) => Err(DatatypeConversionError::ToRbxVariant {
to: d.variant_name(),
from: v.type_name(),
detail: None,
}),
match (self, variant_type) {
(LuaValue::Boolean(b), Rbx::Bool) => Ok(RbxVariant::Bool(*b)),
(LuaValue::Integer(i), Rbx::Int64) => Ok(RbxVariant::Int64(*i as i64)),
(LuaValue::Integer(i), Rbx::Int32) => Ok(RbxVariant::Int32(*i)),
(LuaValue::Integer(i), Rbx::Float64) => Ok(RbxVariant::Float64(*i as f64)),
(LuaValue::Integer(i), Rbx::Float32) => Ok(RbxVariant::Float32(*i as f32)),
(LuaValue::Number(n), Rbx::Int64) => Ok(RbxVariant::Int64(*n as i64)),
(LuaValue::Number(n), Rbx::Int32) => Ok(RbxVariant::Int32(*n as i32)),
(LuaValue::Number(n), Rbx::Float64) => Ok(RbxVariant::Float64(*n)),
(LuaValue::Number(n), Rbx::Float32) => Ok(RbxVariant::Float32(*n as f32)),
(LuaValue::String(s), Rbx::String) => Ok(RbxVariant::String(s.to_str()?.to_string())),
(LuaValue::String(s), Rbx::Content) => {
Ok(RbxVariant::Content(s.to_str()?.to_string().into()))
}
} else {
match self {
// Primitives
LuaValue::Boolean(b) => Ok(RbxVariant::Bool(*b)),
LuaValue::Integer(i) => Ok(RbxVariant::Int32(*i)),
LuaValue::Number(n) => Ok(RbxVariant::Float64(*n)),
LuaValue::String(s) => Ok(RbxVariant::String(s.to_str()?.to_string())),
LuaValue::UserData(u) => u.to_rbx_variant(None),
v => Err(DatatypeConversionError::ToRbxVariant {
to: "Variant",
from: v.type_name(),
detail: None,
}),
(LuaValue::String(s), Rbx::BinaryString) => {
Ok(RbxVariant::BinaryString(STANDARD_NO_PAD.decode(s)?.into()))
}
(LuaValue::UserData(u), d) => u.lua_to_rbx_variant(lua, d),
(v, d) => Err(DatatypeConversionError::ToRbxVariant {
to: d.variant_name(),
from: v.type_name(),
detail: None,
}),
}
}
}
@ -127,18 +108,12 @@ impl<'lua> ToRbxVariant for LuaValue<'lua> {
*/
impl<'lua> FromRbxVariantLua<'lua> for LuaAnyUserData<'lua> {
#[rustfmt::skip]
fn from_rbx_variant_lua(variant: &RbxVariant, lua: &'lua Lua) -> DatatypeConversionResult<Self> {
use RbxVariant as Rbx;
impl<'lua> RbxVariantToLua<'lua> for LuaAnyUserData<'lua> {
fn rbx_variant_to_lua(lua: &'lua Lua, variant: &RbxVariant) -> DatatypeConversionResult<Self> {
use super::types::*;
match variant {
Rbx::UDim(_) => Ok(lua.create_userdata(UDim::from_rbx_variant(variant)?)?),
Rbx::UDim2(_) => Ok(lua.create_userdata(UDim2::from_rbx_variant(variant)?)?),
Rbx::Vector2(_) => Ok(lua.create_userdata(Vector2::from_rbx_variant(variant)?)?),
Rbx::Vector2int16(_) => Ok(lua.create_userdata(Vector2int16::from_rbx_variant(variant)?)?),
Rbx::Vector3(_) => Ok(lua.create_userdata(Vector3::from_rbx_variant(variant)?)?),
Rbx::Vector3int16(_) => Ok(lua.create_userdata(Vector3int16::from_rbx_variant(variant)?)?),
use RbxVariant as Rbx;
Ok(match variant {
// Not yet implemented datatypes
// Rbx::Axes(_) => todo!(),
// Rbx::BrickColor(_) => todo!(),
@ -156,39 +131,51 @@ impl<'lua> FromRbxVariantLua<'lua> for LuaAnyUserData<'lua> {
// Rbx::Rect(_) => todo!(),
// Rbx::Region3(_) => todo!(),
// Rbx::Region3int16(_) => todo!(),
v => Err(DatatypeConversionError::FromRbxVariant {
from: v.variant_name(),
to: "LuaValue",
detail: Some("Type not supported".to_string()),
}),
}
Rbx::UDim(value) => lua.create_userdata(UDim::from(value))?,
Rbx::UDim2(value) => lua.create_userdata(UDim2::from(value))?,
Rbx::Vector2(value) => lua.create_userdata(Vector2::from(value))?,
Rbx::Vector2int16(value) => lua.create_userdata(Vector2int16::from(value))?,
Rbx::Vector3(value) => lua.create_userdata(Vector3::from(value))?,
Rbx::Vector3int16(value) => lua.create_userdata(Vector3int16::from(value))?,
v => {
return Err(DatatypeConversionError::FromRbxVariant {
from: v.variant_name(),
to: "LuaValue",
detail: Some("Type not supported".to_string()),
})
}
})
}
}
impl<'lua> ToRbxVariant for LuaAnyUserData<'lua> {
fn to_rbx_variant(
impl<'lua> LuaToRbxVariant<'lua> for LuaAnyUserData<'lua> {
fn lua_to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
_: &'lua Lua,
variant_type: RbxVariantType,
) -> DatatypeConversionResult<RbxVariant> {
use super::types::*;
if let Ok(u) = self.borrow::<UDim>() {
u.to_rbx_variant(desired_type)
} else if let Ok(u2) = self.borrow::<UDim2>() {
u2.to_rbx_variant(desired_type)
} else if let Ok(v2) = self.borrow::<Vector2>() {
v2.to_rbx_variant(desired_type)
} else if let Ok(v2i) = self.borrow::<Vector2int16>() {
v2i.to_rbx_variant(desired_type)
} else if let Ok(v3) = self.borrow::<Vector3>() {
v3.to_rbx_variant(desired_type)
} else if let Ok(v3i) = self.borrow::<Vector3int16>() {
v3i.to_rbx_variant(desired_type)
Ok(if let Ok(value) = self.borrow::<UDim>() {
RbxVariant::UDim((&*value).into())
} else if let Ok(value) = self.borrow::<UDim2>() {
RbxVariant::UDim2((&*value).into())
} else if let Ok(value) = self.borrow::<Vector2>() {
RbxVariant::Vector2((&*value).into())
} else if let Ok(value) = self.borrow::<Vector2int16>() {
RbxVariant::Vector2int16((&*value).into())
} else if let Ok(value) = self.borrow::<Vector3>() {
RbxVariant::Vector3((&*value).into())
} else if let Ok(value) = self.borrow::<Vector3int16>() {
RbxVariant::Vector3int16((&*value).into())
} else {
Err(DatatypeConversionError::ToRbxVariant {
to: desired_type.map(|d| d.variant_name()).unwrap_or("Variant"),
return Err(DatatypeConversionError::ToRbxVariant {
to: variant_type.variant_name(),
from: "userdata",
detail: None,
})
}
});
})
}
}

View file

@ -7,7 +7,5 @@ mod shared;
pub mod types;
use conversion::*;
use extension::*;
use result::*;
use shared::*;

View file

@ -108,34 +108,3 @@ impl From<&UDim> for RbxUDim {
}
}
}
impl FromRbxVariant for UDim {
fn from_rbx_variant(variant: &RbxVariant) -> DatatypeConversionResult<Self> {
if let RbxVariant::UDim(u) = variant {
Ok(u.into())
} else {
Err(DatatypeConversionError::FromRbxVariant {
from: variant.variant_name(),
to: "UDim",
detail: None,
})
}
}
}
impl ToRbxVariant for UDim {
fn to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
) -> DatatypeConversionResult<RbxVariant> {
if matches!(desired_type, None | Some(RbxVariantType::UDim)) {
Ok(RbxVariant::UDim(self.into()))
} else {
Err(DatatypeConversionError::ToRbxVariant {
to: desired_type.map(|d| d.variant_name()).unwrap_or("?"),
from: "UDim",
detail: None,
})
}
}
}

View file

@ -175,34 +175,3 @@ impl From<&UDim2> for RbxUDim2 {
}
}
}
impl FromRbxVariant for UDim2 {
fn from_rbx_variant(variant: &RbxVariant) -> DatatypeConversionResult<Self> {
if let RbxVariant::UDim2(u) = variant {
Ok(u.into())
} else {
Err(DatatypeConversionError::FromRbxVariant {
from: variant.variant_name(),
to: "UDim2",
detail: None,
})
}
}
}
impl ToRbxVariant for UDim2 {
fn to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
) -> DatatypeConversionResult<RbxVariant> {
if matches!(desired_type, None | Some(RbxVariantType::UDim2)) {
Ok(RbxVariant::UDim2(self.into()))
} else {
Err(DatatypeConversionError::ToRbxVariant {
to: desired_type.map(|d| d.variant_name()).unwrap_or("?"),
from: "UDim2",
detail: None,
})
}
}
}

View file

@ -149,34 +149,3 @@ impl From<&Vector2> for RbxVector2 {
RbxVector2 { x: v.0.x, y: v.0.y }
}
}
impl FromRbxVariant for Vector2 {
fn from_rbx_variant(variant: &RbxVariant) -> DatatypeConversionResult<Self> {
if let RbxVariant::Vector2(v) = variant {
Ok(v.into())
} else {
Err(DatatypeConversionError::FromRbxVariant {
from: variant.variant_name(),
to: "Vector2",
detail: None,
})
}
}
}
impl ToRbxVariant for Vector2 {
fn to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
) -> DatatypeConversionResult<RbxVariant> {
if matches!(desired_type, None | Some(RbxVariantType::Vector2)) {
Ok(RbxVariant::Vector2(self.into()))
} else {
Err(DatatypeConversionError::ToRbxVariant {
to: desired_type.map(|d| d.variant_name()).unwrap_or("?"),
from: "Vector2",
detail: None,
})
}
}
}

View file

@ -130,34 +130,3 @@ impl From<&Vector2int16> for RbxVector2int16 {
}
}
}
impl FromRbxVariant for Vector2int16 {
fn from_rbx_variant(variant: &RbxVariant) -> DatatypeConversionResult<Self> {
if let RbxVariant::Vector2int16(v) = variant {
Ok(v.into())
} else {
Err(DatatypeConversionError::FromRbxVariant {
from: variant.variant_name(),
to: "Vector2int16",
detail: None,
})
}
}
}
impl ToRbxVariant for Vector2int16 {
fn to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
) -> DatatypeConversionResult<RbxVariant> {
if matches!(desired_type, None | Some(RbxVariantType::Vector2int16)) {
Ok(RbxVariant::Vector2int16(self.into()))
} else {
Err(DatatypeConversionError::ToRbxVariant {
to: desired_type.map(|d| d.variant_name()).unwrap_or("?"),
from: "Vector2",
detail: None,
})
}
}
}

View file

@ -171,34 +171,3 @@ impl From<&Vector3> for RbxVector3 {
}
}
}
impl FromRbxVariant for Vector3 {
fn from_rbx_variant(variant: &RbxVariant) -> DatatypeConversionResult<Self> {
if let RbxVariant::Vector3(v) = variant {
Ok(v.into())
} else {
Err(DatatypeConversionError::FromRbxVariant {
from: variant.variant_name(),
to: "Vector3",
detail: None,
})
}
}
}
impl ToRbxVariant for Vector3 {
fn to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
) -> DatatypeConversionResult<RbxVariant> {
if matches!(desired_type, None | Some(RbxVariantType::Vector3)) {
Ok(RbxVariant::Vector3(self.into()))
} else {
Err(DatatypeConversionError::ToRbxVariant {
to: desired_type.map(|d| d.variant_name()).unwrap_or("?"),
from: "Vector2",
detail: None,
})
}
}
}

View file

@ -134,34 +134,3 @@ impl From<&Vector3int16> for RbxVector3int16 {
}
}
}
impl FromRbxVariant for Vector3int16 {
fn from_rbx_variant(variant: &RbxVariant) -> DatatypeConversionResult<Self> {
if let RbxVariant::Vector3int16(v) = variant {
Ok(v.into())
} else {
Err(DatatypeConversionError::FromRbxVariant {
from: variant.variant_name(),
to: "Vector3int16",
detail: None,
})
}
}
}
impl ToRbxVariant for Vector3int16 {
fn to_rbx_variant(
&self,
desired_type: Option<RbxVariantType>,
) -> DatatypeConversionResult<RbxVariant> {
if matches!(desired_type, None | Some(RbxVariantType::Vector3int16)) {
Ok(RbxVariant::Vector3int16(self.into()))
} else {
Err(DatatypeConversionError::ToRbxVariant {
to: desired_type.map(|d| d.variant_name()).unwrap_or("?"),
from: "Vector2",
detail: None,
})
}
}
}