Migrate to mlua 0.10

This commit is contained in:
Filip Tibell 2025-04-23 15:20:53 +02:00
parent ad8822c1e7
commit 6252bc218e
No known key found for this signature in database
132 changed files with 888 additions and 998 deletions

25
Cargo.lock generated
View file

@ -437,9 +437,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.1.30" version = "1.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"
dependencies = [ dependencies = [
"jobserver", "jobserver",
"libc", "libc",
@ -833,6 +833,12 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]] [[package]]
name = "encode_unicode" name = "encode_unicode"
version = "0.3.6" version = "0.3.6"
@ -1539,9 +1545,9 @@ dependencies = [
[[package]] [[package]]
name = "luau0-src" name = "luau0-src"
version = "0.10.3+luau640" version = "0.12.3+luau663"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f39d12b514a676c943990cfbe6200fedcb9c293c8c9219d29be512a6969be92" checksum = "76ae337c644bbf86a8d8e9ce3ee023311833d41741baf5e51acc31b37843aba1"
dependencies = [ dependencies = [
"cc", "cc",
] ]
@ -1841,17 +1847,18 @@ dependencies = [
[[package]] [[package]]
name = "mlua" name = "mlua"
version = "0.9.9" version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7" checksum = "d3f763c1041eff92ffb5d7169968a327e1ed2ebfe425dac0ee5a35f29082534b"
dependencies = [ dependencies = [
"bstr", "bstr",
"either",
"erased-serde", "erased-serde",
"futures-util", "futures-util",
"libloading", "libloading",
"mlua-sys", "mlua-sys",
"num-traits", "num-traits",
"once_cell", "parking_lot",
"rustc-hash 2.0.0", "rustc-hash 2.0.0",
"serde", "serde",
"serde-value", "serde-value",
@ -1878,9 +1885,9 @@ dependencies = [
[[package]] [[package]]
name = "mlua-sys" name = "mlua-sys"
version = "0.6.3" version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebe026d6bd1583a9cf9080e189030ddaea7e6f5f0deb366a8e26f8a26c4135b8" checksum = "1901c1a635a22fe9250ffcc4fcc937c16b47c2e9e71adba8784af8bca1f69594"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if 1.0.0", "cfg-if 1.0.0",

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
glam = "0.27" glam = "0.27"
rand = "0.8" rand = "0.8"

View file

@ -6,7 +6,7 @@ use crate::{datatypes::extension::DomValueExt, instance::Instance};
use super::*; use super::*;
pub(crate) trait LuaToDomValue<'lua> { pub(crate) trait LuaToDomValue {
/** /**
Converts a lua value into a weak dom value. Converts a lua value into a weak dom value.
@ -15,16 +15,16 @@ pub(crate) trait LuaToDomValue<'lua> {
*/ */
fn lua_to_dom_value( fn lua_to_dom_value(
&self, &self,
lua: &'lua Lua, lua: &Lua,
variant_type: Option<DomType>, variant_type: Option<DomType>,
) -> DomConversionResult<DomValue>; ) -> DomConversionResult<DomValue>;
} }
pub(crate) trait DomValueToLua<'lua>: Sized { pub(crate) trait DomValueToLua: Sized {
/** /**
Converts a weak dom value into a lua value. Converts a weak dom value into a lua value.
*/ */
fn dom_value_to_lua(lua: &'lua Lua, variant: &DomValue) -> DomConversionResult<Self>; fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionResult<Self>;
} }
/* /*
@ -37,8 +37,8 @@ pub(crate) trait DomValueToLua<'lua>: Sized {
*/ */
impl<'lua> DomValueToLua<'lua> for LuaValue<'lua> { impl DomValueToLua for LuaValue {
fn dom_value_to_lua(lua: &'lua Lua, variant: &DomValue) -> DomConversionResult<Self> { fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionResult<Self> {
use rbx_dom_weak::types as dom; use rbx_dom_weak::types as dom;
match LuaAnyUserData::dom_value_to_lua(lua, variant) { match LuaAnyUserData::dom_value_to_lua(lua, variant) {
@ -76,10 +76,10 @@ impl<'lua> DomValueToLua<'lua> for LuaValue<'lua> {
} }
} }
impl<'lua> LuaToDomValue<'lua> for LuaValue<'lua> { impl LuaToDomValue for LuaValue {
fn lua_to_dom_value( fn lua_to_dom_value(
&self, &self,
lua: &'lua Lua, lua: &Lua,
variant_type: Option<DomType>, variant_type: Option<DomType>,
) -> DomConversionResult<DomValue> { ) -> DomConversionResult<DomValue> {
use rbx_dom_weak::types as dom; use rbx_dom_weak::types as dom;
@ -102,7 +102,7 @@ impl<'lua> LuaToDomValue<'lua> for LuaValue<'lua> {
Ok(DomValue::String(s.to_str()?.to_string())) Ok(DomValue::String(s.to_str()?.to_string()))
} }
(LuaValue::String(s), DomType::BinaryString) => { (LuaValue::String(s), DomType::BinaryString) => {
Ok(DomValue::BinaryString(s.as_ref().into())) Ok(DomValue::BinaryString(s.as_bytes().to_vec().into()))
} }
(LuaValue::String(s), DomType::ContentId) => { (LuaValue::String(s), DomType::ContentId) => {
Ok(DomValue::ContentId(s.to_str()?.to_string().into())) Ok(DomValue::ContentId(s.to_str()?.to_string().into()))
@ -186,9 +186,9 @@ macro_rules! userdata_to_dom {
}; };
} }
impl<'lua> DomValueToLua<'lua> for LuaAnyUserData<'lua> { impl DomValueToLua for LuaAnyUserData {
#[rustfmt::skip] #[rustfmt::skip]
fn dom_value_to_lua(lua: &'lua Lua, variant: &DomValue) -> DomConversionResult<Self> { fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionResult<Self> {
use super::types::*; use super::types::*;
use rbx_dom_weak::types as dom; use rbx_dom_weak::types as dom;
@ -235,13 +235,9 @@ impl<'lua> DomValueToLua<'lua> for LuaAnyUserData<'lua> {
} }
} }
impl<'lua> LuaToDomValue<'lua> for LuaAnyUserData<'lua> { impl LuaToDomValue for LuaAnyUserData {
#[rustfmt::skip] #[rustfmt::skip]
fn lua_to_dom_value( fn lua_to_dom_value(&self, _: &Lua, variant_type: Option<DomType>) -> DomConversionResult<DomValue> {
&self,
_: &'lua Lua,
variant_type: Option<DomType>,
) -> DomConversionResult<DomValue> {
use super::types::*; use super::types::*;
use rbx_dom_weak::types as dom; use rbx_dom_weak::types as dom;
@ -279,13 +275,13 @@ impl<'lua> LuaToDomValue<'lua> for LuaAnyUserData<'lua> {
// NOTE: The none and default variants of these types are handled in // NOTE: The none and default variants of these types are handled in
// LuaToDomValue for the LuaValue type instead, allowing for nil/default // LuaToDomValue for the LuaValue type instead, allowing for nil/default
DomType::OptionalCFrame => { DomType::OptionalCFrame => {
return match self.borrow::<CFrame>() { match self.borrow::<CFrame>() {
Err(_) => unreachable!("Invalid use of conversion method, should be using LuaValue"), Err(_) => unreachable!("Invalid use of conversion method, should be using LuaValue"),
Ok(value) => Ok(DomValue::OptionalCFrame(Some(dom::CFrame::from(*value)))), Ok(value) => Ok(DomValue::OptionalCFrame(Some(dom::CFrame::from(*value)))),
} }
} }
DomType::PhysicalProperties => { DomType::PhysicalProperties => {
return match self.borrow::<PhysicalProperties>() { match self.borrow::<PhysicalProperties>() {
Err(_) => unreachable!("Invalid use of conversion method, should be using LuaValue"), Err(_) => unreachable!("Invalid use of conversion method, should be using LuaValue"),
Ok(value) => { Ok(value) => {
let props = dom::CustomPhysicalProperties::from(*value); let props = dom::CustomPhysicalProperties::from(*value);

View file

@ -21,11 +21,11 @@ pub struct Axes {
pub(crate) z: bool, pub(crate) z: bool,
} }
impl LuaExportsTable<'_> for Axes { impl LuaExportsTable for Axes {
const EXPORT_NAME: &'static str = "Axes"; const EXPORT_NAME: &'static str = "Axes";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let axes_new = |_, args: LuaMultiValue| { let axes_new = |_: &Lua, args: LuaMultiValue| {
let mut x = false; let mut x = false;
let mut y = false; let mut y = false;
let mut z = false; let mut z = false;
@ -76,7 +76,7 @@ impl LuaExportsTable<'_> for Axes {
} }
impl LuaUserData for Axes { impl LuaUserData for Axes {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("X", |_, this| Ok(this.x)); fields.add_field_method_get("X", |_, this| Ok(this.x));
fields.add_field_method_get("Y", |_, this| Ok(this.y)); fields.add_field_method_get("Y", |_, this| Ok(this.y));
fields.add_field_method_get("Z", |_, this| Ok(this.z)); fields.add_field_method_get("Z", |_, this| Ok(this.z));
@ -88,7 +88,7 @@ impl LuaUserData for Axes {
fields.add_field_method_get("Back", |_, this| Ok(this.z)); fields.add_field_method_get("Back", |_, this| Ok(this.z));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -24,16 +24,16 @@ pub struct BrickColor {
pub(crate) rgb: (u8, u8, u8), pub(crate) rgb: (u8, u8, u8),
} }
impl LuaExportsTable<'_> for BrickColor { impl LuaExportsTable for BrickColor {
const EXPORT_NAME: &'static str = "BrickColor"; const EXPORT_NAME: &'static str = "BrickColor";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
type ArgsNumber = u16; type ArgsNumber = u16;
type ArgsName = String; type ArgsName = String;
type ArgsRgb = (u8, u8, u8); type ArgsRgb = (u8, u8, u8);
type ArgsColor3<'lua> = LuaUserDataRef<'lua, Color3>; type ArgsColor3 = LuaUserDataRef<Color3>;
let brick_color_new = |lua, args: LuaMultiValue| { let brick_color_new = |lua: &Lua, args: LuaMultiValue| {
if let Ok(number) = ArgsNumber::from_lua_multi(args.clone(), lua) { if let Ok(number) = ArgsNumber::from_lua_multi(args.clone(), lua) {
Ok(color_from_number(number)) Ok(color_from_number(number))
} else if let Ok(name) = ArgsName::from_lua_multi(args.clone(), lua) { } else if let Ok(name) = ArgsName::from_lua_multi(args.clone(), lua) {
@ -50,7 +50,7 @@ impl LuaExportsTable<'_> for BrickColor {
} }
}; };
let brick_color_palette = |_, index: u16| { let brick_color_palette = |_: &Lua, index: u16| {
if index == 0 { if index == 0 {
Err(LuaError::RuntimeError("Invalid index".to_string())) Err(LuaError::RuntimeError("Invalid index".to_string()))
} else if let Some(number) = BRICK_COLOR_PALETTE.get((index - 1) as usize) { } else if let Some(number) = BRICK_COLOR_PALETTE.get((index - 1) as usize) {
@ -60,7 +60,7 @@ impl LuaExportsTable<'_> for BrickColor {
} }
}; };
let brick_color_random = |_, ()| { let brick_color_random = |_: &Lua, ()| {
let number = BRICK_COLOR_PALETTE.choose(&mut rand::thread_rng()); let number = BRICK_COLOR_PALETTE.choose(&mut rand::thread_rng());
Ok(color_from_number(*number.unwrap())) Ok(color_from_number(*number.unwrap()))
}; };
@ -71,7 +71,7 @@ impl LuaExportsTable<'_> for BrickColor {
.with_function("random", brick_color_random)?; .with_function("random", brick_color_random)?;
for (name, number) in BRICK_COLOR_CONSTRUCTORS { for (name, number) in BRICK_COLOR_CONSTRUCTORS {
let f = |_, ()| Ok(color_from_number(*number)); let f = |_: &Lua, ()| Ok(color_from_number(*number));
builder = builder.with_function(*name, f)?; builder = builder.with_function(*name, f)?;
} }
@ -80,7 +80,7 @@ impl LuaExportsTable<'_> for BrickColor {
} }
impl LuaUserData for BrickColor { impl LuaUserData for BrickColor {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Number", |_, this| Ok(this.number)); fields.add_field_method_get("Number", |_, this| Ok(this.number));
fields.add_field_method_get("Name", |_, this| Ok(this.name)); fields.add_field_method_get("Name", |_, this| Ok(this.name));
fields.add_field_method_get("R", |_, this| Ok(this.rgb.0 as f32 / 255f32)); fields.add_field_method_get("R", |_, this| Ok(this.rgb.0 as f32 / 255f32));
@ -92,7 +92,7 @@ impl LuaUserData for BrickColor {
fields.add_field_method_get("Color", |_, this| Ok(Color3::from(*this))); fields.add_field_method_get("Color", |_, this| Ok(Color3::from(*this)));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -43,27 +43,28 @@ impl CFrame {
} }
} }
impl LuaExportsTable<'_> for CFrame { impl LuaExportsTable for CFrame {
const EXPORT_NAME: &'static str = "CFrame"; const EXPORT_NAME: &'static str = "CFrame";
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let cframe_angles = |_, (rx, ry, rz): (f32, f32, f32)| { let cframe_angles = |_: &Lua, (rx, ry, rz): (f32, f32, f32)| {
Ok(CFrame(Mat4::from_euler(EulerRot::XYZ, rx, ry, rz))) Ok(CFrame(Mat4::from_euler(EulerRot::XYZ, rx, ry, rz)))
}; };
let cframe_from_axis_angle = let cframe_from_axis_angle = |_: &Lua, (v, r): (LuaUserDataRef<Vector3>, f32)| {
|_, (v, r): (LuaUserDataRef<Vector3>, f32)| Ok(CFrame(Mat4::from_axis_angle(v.0, r))); Ok(CFrame(Mat4::from_axis_angle(v.0, r)))
};
let cframe_from_euler_angles_xyz = |_, (rx, ry, rz): (f32, f32, f32)| { let cframe_from_euler_angles_xyz = |_: &Lua, (rx, ry, rz): (f32, f32, f32)| {
Ok(CFrame(Mat4::from_euler(EulerRot::XYZ, rx, ry, rz))) Ok(CFrame(Mat4::from_euler(EulerRot::XYZ, rx, ry, rz)))
}; };
let cframe_from_euler_angles_yxz = |_, (rx, ry, rz): (f32, f32, f32)| { let cframe_from_euler_angles_yxz = |_: &Lua, (rx, ry, rz): (f32, f32, f32)| {
Ok(CFrame(Mat4::from_euler(EulerRot::YXZ, ry, rx, rz))) Ok(CFrame(Mat4::from_euler(EulerRot::YXZ, ry, rx, rz)))
}; };
let cframe_from_matrix = |_, let cframe_from_matrix = |_: &Lua,
(pos, rx, ry, rz): ( (pos, rx, ry, rz): (
LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>,
LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>,
@ -79,11 +80,11 @@ impl LuaExportsTable<'_> for CFrame {
))) )))
}; };
let cframe_from_orientation = |_, (rx, ry, rz): (f32, f32, f32)| { let cframe_from_orientation = |_: &Lua, (rx, ry, rz): (f32, f32, f32)| {
Ok(CFrame(Mat4::from_euler(EulerRot::YXZ, ry, rx, rz))) Ok(CFrame(Mat4::from_euler(EulerRot::YXZ, ry, rx, rz)))
}; };
let cframe_look_at = |_, let cframe_look_at = |_: &Lua,
(from, to, up): ( (from, to, up): (
LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>,
LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>,
@ -97,18 +98,18 @@ impl LuaExportsTable<'_> for CFrame {
}; };
// Dynamic args constructor // Dynamic args constructor
type ArgsPos<'lua> = LuaUserDataRef<'lua, Vector3>; type ArgsPos = LuaUserDataRef<Vector3>;
type ArgsLook<'lua> = ( type ArgsLook = (
LuaUserDataRef<'lua, Vector3>, LuaUserDataRef<Vector3>,
LuaUserDataRef<'lua, Vector3>, LuaUserDataRef<Vector3>,
Option<LuaUserDataRef<'lua, Vector3>>, Option<LuaUserDataRef<Vector3>>,
); );
type ArgsPosXYZ = (f32, f32, f32); type ArgsPosXYZ = (f32, f32, f32);
type ArgsPosXYZQuat = (f32, f32, f32, f32, f32, f32, f32); type ArgsPosXYZQuat = (f32, f32, f32, f32, f32, f32, f32);
type ArgsMatrix = (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32); type ArgsMatrix = (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32);
let cframe_new = |lua, args: LuaMultiValue| match args.len() { let cframe_new = |lua: &Lua, args: LuaMultiValue| match args.len() {
0 => Ok(CFrame(Mat4::IDENTITY)), 0 => Ok(CFrame(Mat4::IDENTITY)),
1 => match ArgsPos::from_lua_multi(args, lua) { 1 => match ArgsPos::from_lua_multi(args, lua) {
@ -174,7 +175,7 @@ impl LuaExportsTable<'_> for CFrame {
} }
impl LuaUserData for CFrame { impl LuaUserData for CFrame {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Position", |_, this| Ok(Vector3(this.position()))); fields.add_field_method_get("Position", |_, this| Ok(Vector3(this.position())));
fields.add_field_method_get("Rotation", |_, this| { fields.add_field_method_get("Rotation", |_, this| {
Ok(CFrame(Mat4::from_cols( Ok(CFrame(Mat4::from_cols(
@ -200,7 +201,7 @@ impl LuaUserData for CFrame {
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("Inverse", |_, this, ()| Ok(this.inverse())); methods.add_method("Inverse", |_, this, ()| Ok(this.inverse()));
methods.add_method( methods.add_method(
@ -326,7 +327,7 @@ impl LuaUserData for CFrame {
} }
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: rhs.type_name(), from: rhs.type_name(),
to: "userdata", to: "userdata".to_string(),
message: Some(format!( message: Some(format!(
"Expected CFrame or Vector3, got {}", "Expected CFrame or Vector3, got {}",
rhs.type_name() rhs.type_name()

View file

@ -28,11 +28,11 @@ pub struct Color3 {
pub(crate) b: f32, pub(crate) b: f32,
} }
impl LuaExportsTable<'_> for Color3 { impl LuaExportsTable for Color3 {
const EXPORT_NAME: &'static str = "Color3"; const EXPORT_NAME: &'static str = "Color3";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let color3_from_rgb = |_, (r, g, b): (Option<u8>, Option<u8>, Option<u8>)| { let color3_from_rgb = |_: &Lua, (r, g, b): (Option<u8>, Option<u8>, Option<u8>)| {
Ok(Color3 { Ok(Color3 {
r: (r.unwrap_or_default() as f32) / 255f32, r: (r.unwrap_or_default() as f32) / 255f32,
g: (g.unwrap_or_default() as f32) / 255f32, g: (g.unwrap_or_default() as f32) / 255f32,
@ -40,7 +40,7 @@ impl LuaExportsTable<'_> for Color3 {
}) })
}; };
let color3_from_hsv = |_, (h, s, v): (f32, f32, f32)| { let color3_from_hsv = |_: &Lua, (h, s, v): (f32, f32, f32)| {
// https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c // https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
let i = (h * 6.0).floor(); let i = (h * 6.0).floor();
let f = h * 6.0 - i; let f = h * 6.0 - i;
@ -61,7 +61,7 @@ impl LuaExportsTable<'_> for Color3 {
Ok(Color3 { r, g, b }) Ok(Color3 { r, g, b })
}; };
let color3_from_hex = |_, hex: String| { let color3_from_hex = |_: &Lua, hex: String| {
let trimmed = hex.trim_start_matches('#').to_ascii_uppercase(); let trimmed = hex.trim_start_matches('#').to_ascii_uppercase();
let chars = if trimmed.len() == 3 { let chars = if trimmed.len() == 3 {
( (
@ -94,7 +94,7 @@ impl LuaExportsTable<'_> for Color3 {
} }
}; };
let color3_new = |_, (r, g, b): (Option<f32>, Option<f32>, Option<f32>)| { let color3_new = |_: &Lua, (r, g, b): (Option<f32>, Option<f32>, Option<f32>)| {
Ok(Color3 { Ok(Color3 {
r: r.unwrap_or_default(), r: r.unwrap_or_default(),
g: g.unwrap_or_default(), g: g.unwrap_or_default(),
@ -111,14 +111,14 @@ impl LuaExportsTable<'_> for Color3 {
} }
} }
impl<'lua> FromLua<'lua> for Color3 { impl FromLua for Color3 {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::UserData(ud) = value { if let LuaValue::UserData(ud) = value {
Ok(*ud.borrow::<Color3>()?) Ok(*ud.borrow::<Color3>()?)
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "Color3", to: "Color3".to_string(),
message: None, message: None,
}) })
} }
@ -126,13 +126,13 @@ impl<'lua> FromLua<'lua> for Color3 {
} }
impl LuaUserData for Color3 { impl LuaUserData for Color3 {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("R", |_, this| Ok(this.r)); fields.add_field_method_get("R", |_, this| Ok(this.r));
fields.add_field_method_get("G", |_, this| Ok(this.g)); fields.add_field_method_get("G", |_, this| Ok(this.g));
fields.add_field_method_get("B", |_, this| Ok(this.b)); fields.add_field_method_get("B", |_, this| Ok(this.b));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method( methods.add_method(
"Lerp", "Lerp",

View file

@ -21,15 +21,15 @@ pub struct ColorSequence {
pub(crate) keypoints: Vec<ColorSequenceKeypoint>, pub(crate) keypoints: Vec<ColorSequenceKeypoint>,
} }
impl LuaExportsTable<'_> for ColorSequence { impl LuaExportsTable for ColorSequence {
const EXPORT_NAME: &'static str = "ColorSequence"; const EXPORT_NAME: &'static str = "ColorSequence";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
type ArgsColor<'lua> = LuaUserDataRef<'lua, Color3>; type ArgsColor = LuaUserDataRef<Color3>;
type ArgsColors<'lua> = (LuaUserDataRef<'lua, Color3>, LuaUserDataRef<'lua, Color3>); type ArgsColors = (LuaUserDataRef<Color3>, LuaUserDataRef<Color3>);
type ArgsKeypoints<'lua> = Vec<LuaUserDataRef<'lua, ColorSequenceKeypoint>>; type ArgsKeypoints = Vec<LuaUserDataRef<ColorSequenceKeypoint>>;
let color_sequence_new = |lua, args: LuaMultiValue| { let color_sequence_new = |lua: &Lua, args: LuaMultiValue| {
if let Ok(color) = ArgsColor::from_lua_multi(args.clone(), lua) { if let Ok(color) = ArgsColor::from_lua_multi(args.clone(), lua) {
Ok(ColorSequence { Ok(ColorSequence {
keypoints: vec![ keypoints: vec![
@ -75,11 +75,11 @@ impl LuaExportsTable<'_> for ColorSequence {
} }
impl LuaUserData for ColorSequence { impl LuaUserData for ColorSequence {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Keypoints", |_, this| Ok(this.keypoints.clone())); fields.add_field_method_get("Keypoints", |_, this| Ok(this.keypoints.clone()));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -20,16 +20,17 @@ pub struct ColorSequenceKeypoint {
pub(crate) color: Color3, pub(crate) color: Color3,
} }
impl LuaExportsTable<'_> for ColorSequenceKeypoint { impl LuaExportsTable for ColorSequenceKeypoint {
const EXPORT_NAME: &'static str = "ColorSequenceKeypoint"; const EXPORT_NAME: &'static str = "ColorSequenceKeypoint";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let color_sequence_keypoint_new = |_, (time, color): (f32, LuaUserDataRef<Color3>)| { let color_sequence_keypoint_new =
Ok(ColorSequenceKeypoint { |_: &Lua, (time, color): (f32, LuaUserDataRef<Color3>)| {
time, Ok(ColorSequenceKeypoint {
color: *color, time,
}) color: *color,
}; })
};
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("new", color_sequence_keypoint_new)? .with_function("new", color_sequence_keypoint_new)?
@ -38,12 +39,12 @@ impl LuaExportsTable<'_> for ColorSequenceKeypoint {
} }
impl LuaUserData for ColorSequenceKeypoint { impl LuaUserData for ColorSequenceKeypoint {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Time", |_, this| Ok(this.time)); fields.add_field_method_get("Time", |_, this| Ok(this.time));
fields.add_field_method_get("Value", |_, this| Ok(this.color)); fields.add_field_method_get("Value", |_, this| Ok(this.color));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -17,13 +17,13 @@ use super::{super::*, EnumItem};
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct Content(ContentType); pub struct Content(ContentType);
impl LuaExportsTable<'_> for Content { impl LuaExportsTable for Content {
const EXPORT_NAME: &'static str = "Content"; const EXPORT_NAME: &'static str = "Content";
fn create_exports_table(lua: &'_ Lua) -> LuaResult<LuaTable<'_>> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let from_uri = |_, uri: String| Ok(Self(ContentType::Uri(uri))); let from_uri = |_: &Lua, uri: String| Ok(Self(ContentType::Uri(uri)));
let from_object = |_, obj: LuaUserDataRef<Instance>| { let from_object = |_: &Lua, obj: LuaUserDataRef<Instance>| {
let database = rbx_reflection_database::get(); let database = rbx_reflection_database::get();
let instance_descriptor = database let instance_descriptor = database
.classes .classes
@ -48,7 +48,7 @@ impl LuaExportsTable<'_> for Content {
} }
impl LuaUserData for Content { impl LuaUserData for Content {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("SourceType", |_, this| { fields.add_field_method_get("SourceType", |_, this| {
let variant_name = match &this.0 { let variant_name = match &this.0 {
ContentType::None => "None", ContentType::None => "None",
@ -81,14 +81,14 @@ impl LuaUserData for Content {
}); });
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }
} }
impl fmt::Display for Content { impl fmt::Display for Content {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Regardless of the actual content of the Content, Roblox just emits // Regardless of the actual content of the Content, Roblox just emits
// `Content` when casting it to a string. We do not do that. // `Content` when casting it to a string. We do not do that.
write!(f, "Content(")?; write!(f, "Content(")?;

View file

@ -23,7 +23,7 @@ impl Enum {
} }
impl LuaUserData for Enum { impl LuaUserData for Enum {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("GetEnumItems", |_, this, ()| { methods.add_method("GetEnumItems", |_, this, ()| {
Ok(this Ok(this

View file

@ -62,26 +62,26 @@ impl EnumItem {
} }
impl LuaUserData for EnumItem { impl LuaUserData for EnumItem {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Name", |_, this| Ok(this.name.clone())); fields.add_field_method_get("Name", |_, this| Ok(this.name.clone()));
fields.add_field_method_get("Value", |_, this| Ok(this.value)); fields.add_field_method_get("Value", |_, this| Ok(this.value));
fields.add_field_method_get("EnumType", |_, this| Ok(this.parent.clone())); fields.add_field_method_get("EnumType", |_, this| Ok(this.parent.clone()));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }
} }
impl<'lua> FromLua<'lua> for EnumItem { impl FromLua for EnumItem {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::UserData(ud) = value { if let LuaValue::UserData(ud) = value {
Ok(ud.borrow::<EnumItem>()?.to_owned()) Ok(ud.borrow::<EnumItem>()?.to_owned())
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "EnumItem", to: "EnumItem".to_string(),
message: None, message: None,
}) })
} }

View file

@ -13,7 +13,7 @@ use super::{super::*, Enum};
pub struct Enums; pub struct Enums;
impl LuaUserData for Enums { impl LuaUserData for Enums {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("GetEnums", |_, _, ()| { methods.add_method("GetEnums", |_, _, ()| {
let db = rbx_reflection_database::get(); let db = rbx_reflection_database::get();

View file

@ -26,11 +26,11 @@ pub struct Faces {
pub(crate) front: bool, pub(crate) front: bool,
} }
impl LuaExportsTable<'_> for Faces { impl LuaExportsTable for Faces {
const EXPORT_NAME: &'static str = "Faces"; const EXPORT_NAME: &'static str = "Faces";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let faces_new = |_, args: LuaMultiValue| { let faces_new = |_: &Lua, args: LuaMultiValue| {
let mut right = false; let mut right = false;
let mut top = false; let mut top = false;
let mut back = false; let mut back = false;
@ -87,7 +87,7 @@ impl LuaExportsTable<'_> for Faces {
} }
impl LuaUserData for Faces { impl LuaUserData for Faces {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Right", |_, this| Ok(this.right)); fields.add_field_method_get("Right", |_, this| Ok(this.right));
fields.add_field_method_get("Top", |_, this| Ok(this.top)); fields.add_field_method_get("Top", |_, this| Ok(this.top));
fields.add_field_method_get("Back", |_, this| Ok(this.back)); fields.add_field_method_get("Back", |_, this| Ok(this.back));
@ -96,7 +96,7 @@ impl LuaUserData for Faces {
fields.add_field_method_get("Front", |_, this| Ok(this.front)); fields.add_field_method_get("Front", |_, this| Ok(this.front));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -40,11 +40,11 @@ impl Font {
} }
} }
impl LuaExportsTable<'_> for Font { impl LuaExportsTable for Font {
const EXPORT_NAME: &'static str = "Font"; const EXPORT_NAME: &'static str = "Font";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let font_from_enum = |_, value: LuaUserDataRef<EnumItem>| { let font_from_enum = |_: &Lua, value: LuaUserDataRef<EnumItem>| {
if value.parent.desc.name == "Font" { if value.parent.desc.name == "Font" {
match Font::from_enum_item(&value) { match Font::from_enum_item(&value) {
Some(props) => Ok(props), Some(props) => Ok(props),
@ -62,7 +62,7 @@ impl LuaExportsTable<'_> for Font {
}; };
let font_from_name = let font_from_name =
|_, (file, weight, style): (String, Option<FontWeight>, Option<FontStyle>)| { |_: &Lua, (file, weight, style): (String, Option<FontWeight>, Option<FontStyle>)| {
Ok(Font { Ok(Font {
family: format!("rbxasset://fonts/families/{file}.json"), family: format!("rbxasset://fonts/families/{file}.json"),
weight: weight.unwrap_or_default(), weight: weight.unwrap_or_default(),
@ -72,7 +72,7 @@ impl LuaExportsTable<'_> for Font {
}; };
let font_from_id = let font_from_id =
|_, (id, weight, style): (i32, Option<FontWeight>, Option<FontStyle>)| { |_: &Lua, (id, weight, style): (i32, Option<FontWeight>, Option<FontStyle>)| {
Ok(Font { Ok(Font {
family: format!("rbxassetid://{id}"), family: format!("rbxassetid://{id}"),
weight: weight.unwrap_or_default(), weight: weight.unwrap_or_default(),
@ -82,7 +82,7 @@ impl LuaExportsTable<'_> for Font {
}; };
let font_new = let font_new =
|_, (family, weight, style): (String, Option<FontWeight>, Option<FontStyle>)| { |_: &Lua, (family, weight, style): (String, Option<FontWeight>, Option<FontStyle>)| {
Ok(Font { Ok(Font {
family, family,
weight: weight.unwrap_or_default(), weight: weight.unwrap_or_default(),
@ -101,7 +101,7 @@ impl LuaExportsTable<'_> for Font {
} }
impl LuaUserData for Font { impl LuaUserData for Font {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
// Getters // Getters
fields.add_field_method_get("Family", |_, this| Ok(this.family.clone())); fields.add_field_method_get("Family", |_, this| Ok(this.family.clone()));
fields.add_field_method_get("Weight", |_, this| Ok(this.weight)); fields.add_field_method_get("Weight", |_, this| Ok(this.weight));
@ -126,7 +126,7 @@ impl LuaUserData for Font {
}); });
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }
@ -282,8 +282,8 @@ impl std::fmt::Display for FontWeight {
} }
} }
impl<'lua> FromLua<'lua> for FontWeight { impl FromLua for FontWeight {
fn from_lua(lua_value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(lua_value: LuaValue, _: &Lua) -> LuaResult<Self> {
let mut message = None; let mut message = None;
if let LuaValue::UserData(ud) = &lua_value { if let LuaValue::UserData(ud) = &lua_value {
let value = ud.borrow::<EnumItem>()?; let value = ud.borrow::<EnumItem>()?;
@ -304,18 +304,18 @@ impl<'lua> FromLua<'lua> for FontWeight {
} }
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: lua_value.type_name(), from: lua_value.type_name(),
to: "Enum.FontWeight", to: "Enum.FontWeight".to_string(),
message, message,
}) })
} }
} }
impl<'lua> IntoLua<'lua> for FontWeight { impl IntoLua for FontWeight {
fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
match EnumItem::from_enum_name_and_name("FontWeight", self.to_string()) { match EnumItem::from_enum_name_and_name("FontWeight", self.to_string()) {
Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)), Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)),
None => Err(LuaError::ToLuaConversionError { None => Err(LuaError::ToLuaConversionError {
from: "FontWeight", from: "FontWeight".to_string(),
to: "EnumItem", to: "EnumItem",
message: Some(format!("Found unknown Enum.FontWeight value '{self}'")), message: Some(format!("Found unknown Enum.FontWeight value '{self}'")),
}), }),
@ -376,8 +376,8 @@ impl std::fmt::Display for FontStyle {
} }
} }
impl<'lua> FromLua<'lua> for FontStyle { impl FromLua for FontStyle {
fn from_lua(lua_value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(lua_value: LuaValue, _: &Lua) -> LuaResult<Self> {
let mut message = None; let mut message = None;
if let LuaValue::UserData(ud) = &lua_value { if let LuaValue::UserData(ud) = &lua_value {
let value = ud.borrow::<EnumItem>()?; let value = ud.borrow::<EnumItem>()?;
@ -398,18 +398,18 @@ impl<'lua> FromLua<'lua> for FontStyle {
} }
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: lua_value.type_name(), from: lua_value.type_name(),
to: "Enum.FontStyle", to: "Enum.FontStyle".to_string(),
message, message,
}) })
} }
} }
impl<'lua> IntoLua<'lua> for FontStyle { impl IntoLua for FontStyle {
fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
match EnumItem::from_enum_name_and_name("FontStyle", self.to_string()) { match EnumItem::from_enum_name_and_name("FontStyle", self.to_string()) {
Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)), Some(enum_item) => Ok(LuaValue::UserData(lua.create_userdata(enum_item)?)),
None => Err(LuaError::ToLuaConversionError { None => Err(LuaError::ToLuaConversionError {
from: "FontStyle", from: "FontStyle".to_string(),
to: "EnumItem", to: "EnumItem",
message: Some(format!("Found unknown Enum.FontStyle value '{self}'")), message: Some(format!("Found unknown Enum.FontStyle value '{self}'")),
}), }),

View file

@ -20,11 +20,11 @@ pub struct NumberRange {
pub(crate) max: f32, pub(crate) max: f32,
} }
impl LuaExportsTable<'_> for NumberRange { impl LuaExportsTable for NumberRange {
const EXPORT_NAME: &'static str = "NumberRange"; const EXPORT_NAME: &'static str = "NumberRange";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let number_range_new = |_, (min, max): (f32, Option<f32>)| { let number_range_new = |_: &Lua, (min, max): (f32, Option<f32>)| {
Ok(match max { Ok(match max {
Some(max) => NumberRange { Some(max) => NumberRange {
min: min.min(max), min: min.min(max),
@ -41,12 +41,12 @@ impl LuaExportsTable<'_> for NumberRange {
} }
impl LuaUserData for NumberRange { impl LuaUserData for NumberRange {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Min", |_, this| Ok(this.min)); fields.add_field_method_get("Min", |_, this| Ok(this.min));
fields.add_field_method_get("Max", |_, this| Ok(this.max)); fields.add_field_method_get("Max", |_, this| Ok(this.max));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -21,15 +21,15 @@ pub struct NumberSequence {
pub(crate) keypoints: Vec<NumberSequenceKeypoint>, pub(crate) keypoints: Vec<NumberSequenceKeypoint>,
} }
impl LuaExportsTable<'_> for NumberSequence { impl LuaExportsTable for NumberSequence {
const EXPORT_NAME: &'static str = "NumberSequence"; const EXPORT_NAME: &'static str = "NumberSequence";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
type ArgsColor = f32; type ArgsColor = f32;
type ArgsColors = (f32, f32); type ArgsColors = (f32, f32);
type ArgsKeypoints<'lua> = Vec<LuaUserDataRef<'lua, NumberSequenceKeypoint>>; type ArgsKeypoints = Vec<LuaUserDataRef<NumberSequenceKeypoint>>;
let number_sequence_new = |lua, args: LuaMultiValue| { let number_sequence_new = |lua: &Lua, args: LuaMultiValue| {
if let Ok(value) = ArgsColor::from_lua_multi(args.clone(), lua) { if let Ok(value) = ArgsColor::from_lua_multi(args.clone(), lua) {
Ok(NumberSequence { Ok(NumberSequence {
keypoints: vec![ keypoints: vec![
@ -79,11 +79,11 @@ impl LuaExportsTable<'_> for NumberSequence {
} }
impl LuaUserData for NumberSequence { impl LuaUserData for NumberSequence {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Keypoints", |_, this| Ok(this.keypoints.clone())); fields.add_field_method_get("Keypoints", |_, this| Ok(this.keypoints.clone()));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -21,17 +21,18 @@ pub struct NumberSequenceKeypoint {
pub(crate) envelope: f32, pub(crate) envelope: f32,
} }
impl LuaExportsTable<'_> for NumberSequenceKeypoint { impl LuaExportsTable for NumberSequenceKeypoint {
const EXPORT_NAME: &'static str = "NumberSequenceKeypoint"; const EXPORT_NAME: &'static str = "NumberSequenceKeypoint";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let number_sequence_keypoint_new = |_, (time, value, envelope): (f32, f32, Option<f32>)| { let number_sequence_keypoint_new =
Ok(NumberSequenceKeypoint { |_: &Lua, (time, value, envelope): (f32, f32, Option<f32>)| {
time, Ok(NumberSequenceKeypoint {
value, time,
envelope: envelope.unwrap_or_default(), value,
}) envelope: envelope.unwrap_or_default(),
}; })
};
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("new", number_sequence_keypoint_new)? .with_function("new", number_sequence_keypoint_new)?
@ -40,13 +41,13 @@ impl LuaExportsTable<'_> for NumberSequenceKeypoint {
} }
impl LuaUserData for NumberSequenceKeypoint { impl LuaUserData for NumberSequenceKeypoint {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Time", |_, this| Ok(this.time)); fields.add_field_method_get("Time", |_, this| Ok(this.time));
fields.add_field_method_get("Value", |_, this| Ok(this.value)); fields.add_field_method_get("Value", |_, this| Ok(this.value));
fields.add_field_method_get("Envelope", |_, this| Ok(this.envelope)); fields.add_field_method_get("Envelope", |_, this| Ok(this.envelope));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -38,14 +38,14 @@ impl PhysicalProperties {
} }
} }
impl LuaExportsTable<'_> for PhysicalProperties { impl LuaExportsTable for PhysicalProperties {
const EXPORT_NAME: &'static str = "PhysicalProperties"; const EXPORT_NAME: &'static str = "PhysicalProperties";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
type ArgsMaterial<'lua> = LuaUserDataRef<'lua, EnumItem>; type ArgsMaterial = LuaUserDataRef<EnumItem>;
type ArgsNumbers = (f32, f32, f32, Option<f32>, Option<f32>); type ArgsNumbers = (f32, f32, f32, Option<f32>, Option<f32>);
let physical_properties_new = |lua, args: LuaMultiValue| { let physical_properties_new = |lua: &Lua, args: LuaMultiValue| {
if let Ok(value) = ArgsMaterial::from_lua_multi(args.clone(), lua) { if let Ok(value) = ArgsMaterial::from_lua_multi(args.clone(), lua) {
if value.parent.desc.name == "Material" { if value.parent.desc.name == "Material" {
match PhysicalProperties::from_material(&value) { match PhysicalProperties::from_material(&value) {
@ -86,7 +86,7 @@ impl LuaExportsTable<'_> for PhysicalProperties {
} }
impl LuaUserData for PhysicalProperties { impl LuaUserData for PhysicalProperties {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Density", |_, this| Ok(this.density)); fields.add_field_method_get("Density", |_, this| Ok(this.density));
fields.add_field_method_get("Friction", |_, this| Ok(this.friction)); fields.add_field_method_get("Friction", |_, this| Ok(this.friction));
fields.add_field_method_get("FrictionWeight", |_, this| Ok(this.friction_weight)); fields.add_field_method_get("FrictionWeight", |_, this| Ok(this.friction_weight));
@ -94,7 +94,7 @@ impl LuaUserData for PhysicalProperties {
fields.add_field_method_get("ElasticityWeight", |_, this| Ok(this.elasticity_weight)); fields.add_field_method_get("ElasticityWeight", |_, this| Ok(this.elasticity_weight));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -32,12 +32,12 @@ impl Ray {
} }
} }
impl LuaExportsTable<'_> for Ray { impl LuaExportsTable for Ray {
const EXPORT_NAME: &'static str = "Ray"; const EXPORT_NAME: &'static str = "Ray";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let ray_new = let ray_new =
|_, (origin, direction): (LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>)| { |_: &Lua, (origin, direction): (LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>)| {
Ok(Ray { Ok(Ray {
origin: origin.0, origin: origin.0,
direction: direction.0, direction: direction.0,
@ -51,7 +51,7 @@ impl LuaExportsTable<'_> for Ray {
} }
impl LuaUserData for Ray { impl LuaUserData for Ray {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Origin", |_, this| Ok(Vector3(this.origin))); fields.add_field_method_get("Origin", |_, this| Ok(Vector3(this.origin)));
fields.add_field_method_get("Direction", |_, this| Ok(Vector3(this.direction))); fields.add_field_method_get("Direction", |_, this| Ok(Vector3(this.direction)));
fields.add_field_method_get("Unit", |_, this| { fields.add_field_method_get("Unit", |_, this| {
@ -62,7 +62,7 @@ impl LuaUserData for Ray {
}); });
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("ClosestPoint", |_, this, to: LuaUserDataRef<Vector3>| { methods.add_method("ClosestPoint", |_, this, to: LuaUserDataRef<Vector3>| {
Ok(Vector3(this.closest_point(to.0))) Ok(Vector3(this.closest_point(to.0)))

View file

@ -32,17 +32,17 @@ impl Rect {
} }
} }
impl LuaExportsTable<'_> for Rect { impl LuaExportsTable for Rect {
const EXPORT_NAME: &'static str = "Rect"; const EXPORT_NAME: &'static str = "Rect";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
type ArgsVector2s<'lua> = ( type ArgsVector2s = (
Option<LuaUserDataRef<'lua, Vector2>>, Option<LuaUserDataRef<Vector2>>,
Option<LuaUserDataRef<'lua, Vector2>>, Option<LuaUserDataRef<Vector2>>,
); );
type ArgsNums = (Option<f32>, Option<f32>, Option<f32>, Option<f32>); type ArgsNums = (Option<f32>, Option<f32>, Option<f32>, Option<f32>);
let rect_new = |lua, args: LuaMultiValue| { let rect_new = |lua: &Lua, args: LuaMultiValue| {
if let Ok((min, max)) = ArgsVector2s::from_lua_multi(args.clone(), lua) { if let Ok((min, max)) = ArgsVector2s::from_lua_multi(args.clone(), lua) {
Ok(Rect::new( Ok(Rect::new(
min.map(|m| *m).unwrap_or_default().0, min.map(|m| *m).unwrap_or_default().0,
@ -67,14 +67,14 @@ impl LuaExportsTable<'_> for Rect {
} }
impl LuaUserData for Rect { impl LuaUserData for Rect {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Min", |_, this| Ok(Vector2(this.min))); fields.add_field_method_get("Min", |_, this| Ok(Vector2(this.min)));
fields.add_field_method_get("Max", |_, this| Ok(Vector2(this.max))); fields.add_field_method_get("Max", |_, this| Ok(Vector2(this.max)));
fields.add_field_method_get("Width", |_, this| Ok(this.max.x - this.min.x)); fields.add_field_method_get("Width", |_, this| Ok(this.max.x - this.min.x));
fields.add_field_method_get("Height", |_, this| Ok(this.max.y - this.min.y)); fields.add_field_method_get("Height", |_, this| Ok(this.max.y - this.min.y));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm); methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm);

View file

@ -22,16 +22,17 @@ pub struct Region3 {
pub(crate) max: Vec3, pub(crate) max: Vec3,
} }
impl LuaExportsTable<'_> for Region3 { impl LuaExportsTable for Region3 {
const EXPORT_NAME: &'static str = "Region3"; const EXPORT_NAME: &'static str = "Region3";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let region3_new = |_, (min, max): (LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>)| { let region3_new =
Ok(Region3 { |_: &Lua, (min, max): (LuaUserDataRef<Vector3>, LuaUserDataRef<Vector3>)| {
min: min.0, Ok(Region3 {
max: max.0, min: min.0,
}) max: max.0,
}; })
};
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("new", region3_new)? .with_function("new", region3_new)?
@ -40,14 +41,14 @@ impl LuaExportsTable<'_> for Region3 {
} }
impl LuaUserData for Region3 { impl LuaUserData for Region3 {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("CFrame", |_, this| { fields.add_field_method_get("CFrame", |_, this| {
Ok(CFrame(Mat4::from_translation(this.min.lerp(this.max, 0.5)))) Ok(CFrame(Mat4::from_translation(this.min.lerp(this.max, 0.5))))
}); });
fields.add_field_method_get("Size", |_, this| Ok(Vector3(this.max - this.min))); fields.add_field_method_get("Size", |_, this| Ok(Vector3(this.max - this.min)));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("ExpandToGrid", |_, this, resolution: f32| { methods.add_method("ExpandToGrid", |_, this, resolution: f32| {
Ok(Region3 { Ok(Region3 {

View file

@ -22,12 +22,12 @@ pub struct Region3int16 {
pub(crate) max: IVec3, pub(crate) max: IVec3,
} }
impl LuaExportsTable<'_> for Region3int16 { impl LuaExportsTable for Region3int16 {
const EXPORT_NAME: &'static str = "Region3int16"; const EXPORT_NAME: &'static str = "Region3int16";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let region3int16_new = let region3int16_new =
|_, (min, max): (LuaUserDataRef<Vector3int16>, LuaUserDataRef<Vector3int16>)| { |_: &Lua, (min, max): (LuaUserDataRef<Vector3int16>, LuaUserDataRef<Vector3int16>)| {
Ok(Region3int16 { Ok(Region3int16 {
min: min.0, min: min.0,
max: max.0, max: max.0,
@ -41,12 +41,12 @@ impl LuaExportsTable<'_> for Region3int16 {
} }
impl LuaUserData for Region3int16 { impl LuaUserData for Region3int16 {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Min", |_, this| Ok(Vector3int16(this.min))); fields.add_field_method_get("Min", |_, this| Ok(Vector3int16(this.min)));
fields.add_field_method_get("Max", |_, this| Ok(Vector3int16(this.max))); fields.add_field_method_get("Max", |_, this| Ok(Vector3int16(this.max)));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -27,11 +27,11 @@ impl UDim {
} }
} }
impl LuaExportsTable<'_> for UDim { impl LuaExportsTable for UDim {
const EXPORT_NAME: &'static str = "UDim"; const EXPORT_NAME: &'static str = "UDim";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let udim_new = |_, (scale, offset): (Option<f32>, Option<i32>)| { let udim_new = |_: &Lua, (scale, offset): (Option<f32>, Option<i32>)| {
Ok(UDim { Ok(UDim {
scale: scale.unwrap_or_default(), scale: scale.unwrap_or_default(),
offset: offset.unwrap_or_default(), offset: offset.unwrap_or_default(),
@ -45,12 +45,12 @@ impl LuaExportsTable<'_> for UDim {
} }
impl LuaUserData for UDim { impl LuaUserData for UDim {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Scale", |_, this| Ok(this.scale)); fields.add_field_method_get("Scale", |_, this| Ok(this.scale));
fields.add_field_method_get("Offset", |_, this| Ok(this.offset)); fields.add_field_method_get("Offset", |_, this| Ok(this.offset));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm); methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm);

View file

@ -24,30 +24,27 @@ pub struct UDim2 {
pub(crate) y: UDim, pub(crate) y: UDim,
} }
impl LuaExportsTable<'_> for UDim2 { impl LuaExportsTable for UDim2 {
const EXPORT_NAME: &'static str = "UDim2"; const EXPORT_NAME: &'static str = "UDim2";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let udim2_from_offset = |_, (x, y): (Option<i32>, Option<i32>)| { let udim2_from_offset = |_: &Lua, (x, y): (Option<i32>, Option<i32>)| {
Ok(UDim2 { Ok(UDim2 {
x: UDim::new(0f32, x.unwrap_or_default()), x: UDim::new(0f32, x.unwrap_or_default()),
y: UDim::new(0f32, y.unwrap_or_default()), y: UDim::new(0f32, y.unwrap_or_default()),
}) })
}; };
let udim2_from_scale = |_, (x, y): (Option<f32>, Option<f32>)| { let udim2_from_scale = |_: &Lua, (x, y): (Option<f32>, Option<f32>)| {
Ok(UDim2 { Ok(UDim2 {
x: UDim::new(x.unwrap_or_default(), 0), x: UDim::new(x.unwrap_or_default(), 0),
y: UDim::new(y.unwrap_or_default(), 0), y: UDim::new(y.unwrap_or_default(), 0),
}) })
}; };
type ArgsUDims<'lua> = ( type ArgsUDims = (Option<LuaUserDataRef<UDim>>, Option<LuaUserDataRef<UDim>>);
Option<LuaUserDataRef<'lua, UDim>>,
Option<LuaUserDataRef<'lua, UDim>>,
);
type ArgsNums = (Option<f32>, Option<i32>, Option<f32>, Option<i32>); type ArgsNums = (Option<f32>, Option<i32>, Option<f32>, Option<i32>);
let udim2_new = |lua, args: LuaMultiValue| { let udim2_new = |lua: &Lua, args: LuaMultiValue| {
if let Ok((x, y)) = ArgsUDims::from_lua_multi(args.clone(), lua) { if let Ok((x, y)) = ArgsUDims::from_lua_multi(args.clone(), lua) {
Ok(UDim2 { Ok(UDim2 {
x: x.map(|x| *x).unwrap_or_default(), x: x.map(|x| *x).unwrap_or_default(),
@ -75,14 +72,14 @@ impl LuaExportsTable<'_> for UDim2 {
} }
impl LuaUserData for UDim2 { impl LuaUserData for UDim2 {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("X", |_, this| Ok(this.x)); fields.add_field_method_get("X", |_, this| Ok(this.x));
fields.add_field_method_get("Y", |_, this| Ok(this.y)); fields.add_field_method_get("Y", |_, this| Ok(this.y));
fields.add_field_method_get("Width", |_, this| Ok(this.x)); fields.add_field_method_get("Width", |_, this| Ok(this.x));
fields.add_field_method_get("Height", |_, this| Ok(this.y)); fields.add_field_method_get("Height", |_, this| Ok(this.y));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method( methods.add_method(
"Lerp", "Lerp",

View file

@ -21,11 +21,11 @@ use super::super::*;
#[derive(Debug, Clone, Copy, PartialEq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Vector2(pub Vec2); pub struct Vector2(pub Vec2);
impl LuaExportsTable<'_> for Vector2 { impl LuaExportsTable for Vector2 {
const EXPORT_NAME: &'static str = "Vector2"; const EXPORT_NAME: &'static str = "Vector2";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let vector2_new = |_, (x, y): (Option<f32>, Option<f32>)| { let vector2_new = |_: &Lua, (x, y): (Option<f32>, Option<f32>)| {
Ok(Vector2(Vec2 { Ok(Vector2(Vec2 {
x: x.unwrap_or_default(), x: x.unwrap_or_default(),
y: y.unwrap_or_default(), y: y.unwrap_or_default(),
@ -43,14 +43,14 @@ impl LuaExportsTable<'_> for Vector2 {
} }
impl LuaUserData for Vector2 { impl LuaUserData for Vector2 {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Magnitude", |_, this| Ok(this.0.length())); fields.add_field_method_get("Magnitude", |_, this| Ok(this.0.length()));
fields.add_field_method_get("Unit", |_, this| Ok(Vector2(this.0.normalize()))); fields.add_field_method_get("Unit", |_, this| Ok(Vector2(this.0.normalize())));
fields.add_field_method_get("X", |_, this| Ok(this.0.x)); fields.add_field_method_get("X", |_, this| Ok(this.0.x));
fields.add_field_method_get("Y", |_, this| Ok(this.0.y)); fields.add_field_method_get("Y", |_, this| Ok(this.0.y));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("Angle", |_, this, rhs: LuaUserDataRef<Vector2>| { methods.add_method("Angle", |_, this, rhs: LuaUserDataRef<Vector2>| {
Ok(this.0.angle_between(rhs.0)) Ok(this.0.angle_between(rhs.0))

View file

@ -21,11 +21,11 @@ use super::super::*;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vector2int16(pub IVec2); pub struct Vector2int16(pub IVec2);
impl LuaExportsTable<'_> for Vector2int16 { impl LuaExportsTable for Vector2int16 {
const EXPORT_NAME: &'static str = "Vector2int16"; const EXPORT_NAME: &'static str = "Vector2int16";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let vector2int16_new = |_, (x, y): (Option<i16>, Option<i16>)| { let vector2int16_new = |_: &Lua, (x, y): (Option<i16>, Option<i16>)| {
Ok(Vector2int16(IVec2 { Ok(Vector2int16(IVec2 {
x: x.unwrap_or_default() as i32, x: x.unwrap_or_default() as i32,
y: y.unwrap_or_default() as i32, y: y.unwrap_or_default() as i32,
@ -39,12 +39,12 @@ impl LuaExportsTable<'_> for Vector2int16 {
} }
impl LuaUserData for Vector2int16 { impl LuaUserData for Vector2int16 {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("X", |_, this| Ok(this.0.x)); fields.add_field_method_get("X", |_, this| Ok(this.0.x));
fields.add_field_method_get("Y", |_, this| Ok(this.0.y)); fields.add_field_method_get("Y", |_, this| Ok(this.0.y));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm); methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm);

View file

@ -24,11 +24,11 @@ use super::{super::*, EnumItem};
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vector3(pub Vec3); pub struct Vector3(pub Vec3);
impl LuaExportsTable<'_> for Vector3 { impl LuaExportsTable for Vector3 {
const EXPORT_NAME: &'static str = "Vector3"; const EXPORT_NAME: &'static str = "Vector3";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let vector3_from_axis = |_, normal_id: LuaUserDataRef<EnumItem>| { let vector3_from_axis = |_: &Lua, normal_id: LuaUserDataRef<EnumItem>| {
if normal_id.parent.desc.name == "Axis" { if normal_id.parent.desc.name == "Axis" {
Ok(match normal_id.name.as_str() { Ok(match normal_id.name.as_str() {
"X" => Vector3(Vec3::X), "X" => Vector3(Vec3::X),
@ -48,7 +48,7 @@ impl LuaExportsTable<'_> for Vector3 {
} }
}; };
let vector3_from_normal_id = |_, normal_id: LuaUserDataRef<EnumItem>| { let vector3_from_normal_id = |_: &Lua, normal_id: LuaUserDataRef<EnumItem>| {
if normal_id.parent.desc.name == "NormalId" { if normal_id.parent.desc.name == "NormalId" {
Ok(match normal_id.name.as_str() { Ok(match normal_id.name.as_str() {
"Left" => Vector3(Vec3::X), "Left" => Vector3(Vec3::X),
@ -71,7 +71,7 @@ impl LuaExportsTable<'_> for Vector3 {
} }
}; };
let vector3_new = |_, (x, y, z): (Option<f32>, Option<f32>, Option<f32>)| { let vector3_new = |_: &Lua, (x, y, z): (Option<f32>, Option<f32>, Option<f32>)| {
Ok(Vector3(Vec3 { Ok(Vector3(Vec3 {
x: x.unwrap_or_default(), x: x.unwrap_or_default(),
y: y.unwrap_or_default(), y: y.unwrap_or_default(),
@ -93,7 +93,7 @@ impl LuaExportsTable<'_> for Vector3 {
} }
impl LuaUserData for Vector3 { impl LuaUserData for Vector3 {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Magnitude", |_, this| Ok(this.0.length())); fields.add_field_method_get("Magnitude", |_, this| Ok(this.0.length()));
fields.add_field_method_get("Unit", |_, this| Ok(Vector3(this.0.normalize()))); fields.add_field_method_get("Unit", |_, this| Ok(Vector3(this.0.normalize())));
fields.add_field_method_get("X", |_, this| Ok(this.0.x)); fields.add_field_method_get("X", |_, this| Ok(this.0.x));
@ -101,7 +101,7 @@ impl LuaUserData for Vector3 {
fields.add_field_method_get("Z", |_, this| Ok(this.0.z)); fields.add_field_method_get("Z", |_, this| Ok(this.0.z));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Methods // Methods
methods.add_method("Angle", |_, this, rhs: LuaUserDataRef<Vector3>| { methods.add_method("Angle", |_, this, rhs: LuaUserDataRef<Vector3>| {
Ok(this.0.angle_between(rhs.0)) Ok(this.0.angle_between(rhs.0))

View file

@ -21,11 +21,11 @@ use super::super::*;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vector3int16(pub IVec3); pub struct Vector3int16(pub IVec3);
impl LuaExportsTable<'_> for Vector3int16 { impl LuaExportsTable for Vector3int16 {
const EXPORT_NAME: &'static str = "Vector3int16"; const EXPORT_NAME: &'static str = "Vector3int16";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let vector3int16_new = |_, (x, y, z): (Option<i16>, Option<i16>, Option<i16>)| { let vector3int16_new = |_: &Lua, (x, y, z): (Option<i16>, Option<i16>, Option<i16>)| {
Ok(Vector3int16(IVec3 { Ok(Vector3int16(IVec3 {
x: x.unwrap_or_default() as i32, x: x.unwrap_or_default() as i32,
y: y.unwrap_or_default() as i32, y: y.unwrap_or_default() as i32,
@ -40,13 +40,13 @@ impl LuaExportsTable<'_> for Vector3int16 {
} }
impl LuaUserData for Vector3int16 { impl LuaUserData for Vector3int16 {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("X", |_, this| Ok(this.0.x)); fields.add_field_method_get("X", |_, this| Ok(this.0.x));
fields.add_field_method_get("Y", |_, this| Ok(this.0.y)); fields.add_field_method_get("Y", |_, this| Ok(this.0.y));
fields.add_field_method_get("Z", |_, this| Ok(this.0.z)); fields.add_field_method_get("Z", |_, this| Ok(this.0.z));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm); methods.add_meta_method(LuaMetaMethod::Unm, userdata_impl_unm);

View file

@ -18,10 +18,10 @@ use mlua::prelude::*;
} }
} }
impl LuaExportsTable<'_> for MyType { impl LuaExportsTable for MyType {
const EXPORT_NAME: &'static str = "MyType"; const EXPORT_NAME: &'static str = "MyType";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let my_type_new = |lua, n: Option<usize>| { let my_type_new = |lua, n: Option<usize>| {
Self::new(n.unwrap_or_default()) Self::new(n.unwrap_or_default())
}; };
@ -37,10 +37,10 @@ use mlua::prelude::*;
} }
``` ```
*/ */
pub trait LuaExportsTable<'lua> { pub trait LuaExportsTable {
const EXPORT_NAME: &'static str; const EXPORT_NAME: &'static str;
fn create_exports_table(lua: &'lua Lua) -> LuaResult<LuaTable<'lua>>; fn create_exports_table(lua: Lua) -> LuaResult<LuaTable>;
} }
/** /**
@ -57,12 +57,12 @@ pub trait LuaExportsTable<'lua> {
let (name2, table2) = export::<Type2>(lua)?; let (name2, table2) = export::<Type2>(lua)?;
``` ```
*/ */
pub fn export<'lua, T>(lua: &'lua Lua) -> LuaResult<(&'static str, LuaValue<'lua>)> pub fn export<T>(lua: Lua) -> LuaResult<(&'static str, LuaValue)>
where where
T: LuaExportsTable<'lua>, T: LuaExportsTable,
{ {
Ok(( Ok((
T::EXPORT_NAME, T::EXPORT_NAME,
<T as LuaExportsTable>::create_exports_table(lua)?.into_lua(lua)?, <T as LuaExportsTable>::create_exports_table(lua.clone())?.into_lua(&lua)?,
)) ))
} }

View file

@ -20,7 +20,7 @@ use crate::{
use super::{data_model, registry::InstanceRegistry, Instance}; use super::{data_model, registry::InstanceRegistry, Instance};
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(m: &mut M) { pub fn add_methods<M: LuaUserDataMethods<Instance>>(m: &mut M) {
m.add_meta_method(LuaMetaMethod::ToString, |lua, this, ()| { m.add_meta_method(LuaMetaMethod::ToString, |lua, this, ()| {
ensure_not_destroyed(this)?; ensure_not_destroyed(this)?;
userdata_impl_to_string(lua, this, ()) userdata_impl_to_string(lua, this, ())
@ -211,11 +211,7 @@ fn ensure_not_destroyed(inst: &Instance) -> LuaResult<()> {
3. Get a current child of the instance 3. Get a current child of the instance
4. No valid property or instance found, throw error 4. No valid property or instance found, throw error
*/ */
fn instance_property_get<'lua>( fn instance_property_get(lua: &Lua, this: &Instance, prop_name: String) -> LuaResult<LuaValue> {
lua: &'lua Lua,
this: &Instance,
prop_name: String,
) -> LuaResult<LuaValue<'lua>> {
match prop_name.as_str() { match prop_name.as_str() {
"ClassName" => return this.get_class_name().into_lua(lua), "ClassName" => return this.get_class_name().into_lua(lua),
"Parent" => { "Parent" => {
@ -295,10 +291,10 @@ fn instance_property_get<'lua>(
2a. Set a strict enum from a given EnumItem OR 2a. Set a strict enum from a given EnumItem OR
2b. Set a normal property from a given value 2b. Set a normal property from a given value
*/ */
fn instance_property_set<'lua>( fn instance_property_set(
lua: &'lua Lua, lua: &Lua,
this: &mut Instance, this: &mut Instance,
(prop_name, prop_value): (String, LuaValue<'lua>), (prop_name, prop_value): (String, LuaValue),
) -> LuaResult<()> { ) -> LuaResult<()> {
ensure_not_destroyed(this)?; ensure_not_destroyed(this)?;
@ -319,7 +315,7 @@ fn instance_property_set<'lua>(
"Failed to set Parent - DataModel can not be reparented".to_string(), "Failed to set Parent - DataModel can not be reparented".to_string(),
)); ));
} }
type Parent<'lua> = Option<LuaUserDataRef<'lua, Instance>>; type Parent = Option<LuaUserDataRef<Instance>>;
let parent = Parent::from_lua(prop_value, lua)?; let parent = Parent::from_lua(prop_value, lua)?;
this.set_parent(parent.map(|p| *p)); this.set_parent(parent.map(|p| *p));
return Ok(()); return Ok(());

View file

@ -12,11 +12,11 @@ use super::Instance;
pub const CLASS_NAME: &str = "DataModel"; pub const CLASS_NAME: &str = "DataModel";
pub fn add_fields<'lua, F: LuaUserDataFields<'lua, Instance>>(f: &mut F) { pub fn add_fields<F: LuaUserDataFields<Instance>>(f: &mut F) {
add_class_restricted_getter(f, CLASS_NAME, "Workspace", data_model_get_workspace); add_class_restricted_getter(f, CLASS_NAME, "Workspace", data_model_get_workspace);
} }
pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(m: &mut M) { pub fn add_methods<M: LuaUserDataMethods<Instance>>(m: &mut M) {
add_class_restricted_method(m, CLASS_NAME, "GetService", data_model_get_service); add_class_restricted_method(m, CLASS_NAME, "GetService", data_model_get_service);
add_class_restricted_method(m, CLASS_NAME, "FindService", data_model_find_service); add_class_restricted_method(m, CLASS_NAME, "FindService", data_model_find_service);
} }

View file

@ -723,11 +723,11 @@ impl Instance {
} }
} }
impl LuaExportsTable<'_> for Instance { impl LuaExportsTable for Instance {
const EXPORT_NAME: &'static str = "Instance"; const EXPORT_NAME: &'static str = "Instance";
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> { fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
let instance_new = |lua, class_name: String| { let instance_new = |lua: &Lua, class_name: String| {
if class_exists(&class_name) { if class_exists(&class_name) {
Instance::new_orphaned(class_name).into_lua(lua) Instance::new_orphaned(class_name).into_lua(lua)
} else { } else {
@ -756,12 +756,12 @@ impl LuaExportsTable<'_> for Instance {
instance registry, and register properties + methods from the lua side instance registry, and register properties + methods from the lua side
*/ */
impl LuaUserData for Instance { impl LuaUserData for Instance {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
data_model::add_fields(fields); data_model::add_fields(fields);
workspace::add_fields(fields); workspace::add_fields(fields);
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
base::add_methods(methods); base::add_methods(methods);
data_model::add_methods(methods); data_model::add_methods(methods);
terrain::add_methods(methods); terrain::add_methods(methods);

View file

@ -58,11 +58,11 @@ impl InstanceRegistry {
- If the method already exists in the registry. - If the method already exists in the registry.
*/ */
pub fn insert_method<'lua>( pub fn insert_method(
lua: &'lua Lua, lua: &Lua,
class_name: &str, class_name: &str,
method_name: &str, method_name: &str,
method: LuaFunction<'lua>, method: LuaFunction,
) -> Result<(), InstanceRegistryError> { ) -> Result<(), InstanceRegistryError> {
let registry = Self::get_or_create(lua); let registry = Self::get_or_create(lua);
@ -94,11 +94,11 @@ impl InstanceRegistry {
- If the property already exists in the registry. - If the property already exists in the registry.
*/ */
pub fn insert_property_getter<'lua>( pub fn insert_property_getter(
lua: &'lua Lua, lua: &Lua,
class_name: &str, class_name: &str,
property_name: &str, property_name: &str,
property_getter: LuaFunction<'lua>, property_getter: LuaFunction,
) -> Result<(), InstanceRegistryError> { ) -> Result<(), InstanceRegistryError> {
let registry = Self::get_or_create(lua); let registry = Self::get_or_create(lua);
@ -130,11 +130,11 @@ impl InstanceRegistry {
- If the property already exists in the registry. - If the property already exists in the registry.
*/ */
pub fn insert_property_setter<'lua>( pub fn insert_property_setter(
lua: &'lua Lua, lua: &Lua,
class_name: &str, class_name: &str,
property_name: &str, property_name: &str,
property_setter: LuaFunction<'lua>, property_setter: LuaFunction,
) -> Result<(), InstanceRegistryError> { ) -> Result<(), InstanceRegistryError> {
let registry = Self::get_or_create(lua); let registry = Self::get_or_create(lua);
@ -165,11 +165,7 @@ impl InstanceRegistry {
Returns `None` if the method is not found. Returns `None` if the method is not found.
*/ */
#[must_use] #[must_use]
pub fn find_method<'lua>( pub fn find_method(lua: &Lua, instance: &Instance, method_name: &str) -> Option<LuaFunction> {
lua: &'lua Lua,
instance: &Instance,
method_name: &str,
) -> Option<LuaFunction<'lua>> {
let registry = Self::get_or_create(lua); let registry = Self::get_or_create(lua);
let methods = registry let methods = registry
.methods .methods
@ -192,11 +188,11 @@ impl InstanceRegistry {
Returns `None` if the property getter is not found. Returns `None` if the property getter is not found.
*/ */
#[must_use] #[must_use]
pub fn find_property_getter<'lua>( pub fn find_property_getter(
lua: &'lua Lua, lua: &Lua,
instance: &Instance, instance: &Instance,
property_name: &str, property_name: &str,
) -> Option<LuaFunction<'lua>> { ) -> Option<LuaFunction> {
let registry = Self::get_or_create(lua); let registry = Self::get_or_create(lua);
let getters = registry let getters = registry
.getters .getters
@ -219,11 +215,11 @@ impl InstanceRegistry {
Returns `None` if the property setter is not found. Returns `None` if the property setter is not found.
*/ */
#[must_use] #[must_use]
pub fn find_property_setter<'lua>( pub fn find_property_setter(
lua: &'lua Lua, lua: &Lua,
instance: &Instance, instance: &Instance,
property_name: &str, property_name: &str,
) -> Option<LuaFunction<'lua>> { ) -> Option<LuaFunction> {
let registry = Self::get_or_create(lua); let registry = Self::get_or_create(lua);
let setters = registry let setters = registry
.setters .setters

View file

@ -10,7 +10,7 @@ use super::Instance;
pub const CLASS_NAME: &str = "Terrain"; pub const CLASS_NAME: &str = "Terrain";
pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(methods: &mut M) { pub fn add_methods<M: LuaUserDataMethods<Instance>>(methods: &mut M) {
add_class_restricted_method( add_class_restricted_method(
methods, methods,
CLASS_NAME, CLASS_NAME,

View file

@ -6,7 +6,7 @@ use super::Instance;
pub const CLASS_NAME: &str = "Workspace"; pub const CLASS_NAME: &str = "Workspace";
pub fn add_fields<'lua, F: LuaUserDataFields<'lua, Instance>>(f: &mut F) { pub fn add_fields<F: LuaUserDataFields<Instance>>(f: &mut F) {
add_class_restricted_getter(f, CLASS_NAME, "Terrain", workspace_get_terrain); add_class_restricted_getter(f, CLASS_NAME, "Terrain", workspace_get_terrain);
add_class_restricted_getter(f, CLASS_NAME, "CurrentCamera", workspace_get_camera); add_class_restricted_getter(f, CLASS_NAME, "CurrentCamera", workspace_get_camera);
} }

View file

@ -14,38 +14,38 @@ pub(crate) mod shared;
use exports::export; use exports::export;
fn create_all_exports(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> { fn create_all_exports(lua: Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> {
use datatypes::types::*; use datatypes::types::*;
use instance::Instance; use instance::Instance;
Ok(vec![ Ok(vec![
// Datatypes // Datatypes
export::<Axes>(lua)?, export::<Axes>(lua.clone())?,
export::<BrickColor>(lua)?, export::<BrickColor>(lua.clone())?,
export::<CFrame>(lua)?, export::<CFrame>(lua.clone())?,
export::<Color3>(lua)?, export::<Color3>(lua.clone())?,
export::<ColorSequence>(lua)?, export::<ColorSequence>(lua.clone())?,
export::<ColorSequenceKeypoint>(lua)?, export::<ColorSequenceKeypoint>(lua.clone())?,
export::<Content>(lua)?, export::<Content>(lua.clone())?,
export::<Faces>(lua)?, export::<Faces>(lua.clone())?,
export::<Font>(lua)?, export::<Font>(lua.clone())?,
export::<NumberRange>(lua)?, export::<NumberRange>(lua.clone())?,
export::<NumberSequence>(lua)?, export::<NumberSequence>(lua.clone())?,
export::<NumberSequenceKeypoint>(lua)?, export::<NumberSequenceKeypoint>(lua.clone())?,
export::<PhysicalProperties>(lua)?, export::<PhysicalProperties>(lua.clone())?,
export::<Ray>(lua)?, export::<Ray>(lua.clone())?,
export::<Rect>(lua)?, export::<Rect>(lua.clone())?,
export::<UDim>(lua)?, export::<UDim>(lua.clone())?,
export::<UDim2>(lua)?, export::<UDim2>(lua.clone())?,
export::<Region3>(lua)?, export::<Region3>(lua.clone())?,
export::<Region3int16>(lua)?, export::<Region3int16>(lua.clone())?,
export::<Vector2>(lua)?, export::<Vector2>(lua.clone())?,
export::<Vector2int16>(lua)?, export::<Vector2int16>(lua.clone())?,
export::<Vector3>(lua)?, export::<Vector3>(lua.clone())?,
export::<Vector3int16>(lua)?, export::<Vector3int16>(lua.clone())?,
// Classes // Classes
export::<Instance>(lua)?, export::<Instance>(lua.clone())?,
// Singletons // Singletons
("Enum", Enums.into_lua(lua)?), ("Enum", Enums.into_lua(&lua)?),
]) ])
} }
@ -59,13 +59,13 @@ fn create_all_exports(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> {
Errors when out of memory or when a value cannot be created. Errors when out of memory or when a value cannot be created.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
// FUTURE: We can probably create these lazily as users // FUTURE: We can probably create these lazily as users
// index the main exports (this return value) table and // index the main exports (this return value) table and
// save some memory and startup time. The full exports // save some memory and startup time. The full exports
// table is quite big and probably won't get any smaller // table is quite big and probably won't get any smaller
// since we impl all roblox constructors for each datatype. // since we impl all roblox constructors for each datatype.
let exports = create_all_exports(lua)?; let exports = create_all_exports(lua.clone())?;
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_values(exports)? .with_values(exports)?
.build_readonly() .build_readonly()

View file

@ -85,7 +85,7 @@ impl DatabaseClass {
} }
impl LuaUserData for DatabaseClass { impl LuaUserData for DatabaseClass {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Name", |_, this| Ok(this.get_name())); fields.add_field_method_get("Name", |_, this| Ok(this.get_name()));
fields.add_field_method_get("Superclass", |_, this| Ok(this.get_superclass())); fields.add_field_method_get("Superclass", |_, this| Ok(this.get_superclass()));
fields.add_field_method_get("Properties", |_, this| Ok(this.get_properties())); fields.add_field_method_get("Properties", |_, this| Ok(this.get_properties()));
@ -108,7 +108,7 @@ impl LuaUserData for DatabaseClass {
fields.add_field_method_get("Tags", |_, this| Ok(this.get_tags_str())); fields.add_field_method_get("Tags", |_, this| Ok(this.get_tags_str()));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -45,12 +45,12 @@ impl DatabaseEnum {
} }
impl LuaUserData for DatabaseEnum { impl LuaUserData for DatabaseEnum {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Name", |_, this| Ok(this.get_name())); fields.add_field_method_get("Name", |_, this| Ok(this.get_name()));
fields.add_field_method_get("Items", |_, this| Ok(this.get_items())); fields.add_field_method_get("Items", |_, this| Ok(this.get_items()));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -111,11 +111,11 @@ impl Database {
} }
impl LuaUserData for Database { impl LuaUserData for Database {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Version", |_, this| Ok(this.get_version())); fields.add_field_method_get("Version", |_, this| Ok(this.get_version()));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
methods.add_method("GetEnumNames", |_, this, (): ()| Ok(this.get_enum_names())); methods.add_method("GetEnumNames", |_, this, (): ()| Ok(this.get_enum_names()));

View file

@ -69,14 +69,14 @@ impl DatabaseProperty {
} }
impl LuaUserData for DatabaseProperty { impl LuaUserData for DatabaseProperty {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("Name", |_, this| Ok(this.get_name())); fields.add_field_method_get("Name", |_, this| Ok(this.get_name()));
fields.add_field_method_get("Datatype", |_, this| Ok(this.get_datatype_name())); fields.add_field_method_get("Datatype", |_, this| Ok(this.get_datatype_name()));
fields.add_field_method_get("Scriptability", |_, this| Ok(this.get_scriptability_str())); fields.add_field_method_get("Scriptability", |_, this| Ok(this.get_scriptability_str()));
fields.add_field_method_get("Tags", |_, this| Ok(this.get_tags_str())); fields.add_field_method_get("Tags", |_, this| Ok(this.get_tags_str()));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
} }

View file

@ -6,14 +6,14 @@ use crate::instance::Instance;
use super::instance::class_is_a; use super::instance::class_is_a;
pub(crate) fn add_class_restricted_getter<'lua, F: LuaUserDataFields<'lua, Instance>, R, G>( pub(crate) fn add_class_restricted_getter<F: LuaUserDataFields<Instance>, R, G>(
fields: &mut F, fields: &mut F,
class_name: &'static str, class_name: &'static str,
field_name: &'static str, field_name: &'static str,
field_getter: G, field_getter: G,
) where ) where
R: IntoLua<'lua>, R: IntoLua,
G: 'static + Fn(&'lua Lua, &Instance) -> LuaResult<R>, G: 'static + Fn(&Lua, &Instance) -> LuaResult<R>,
{ {
fields.add_field_method_get(field_name, move |lua, this| { fields.add_field_method_get(field_name, move |lua, this| {
if class_is_a(this.get_class_name(), class_name).unwrap_or(false) { if class_is_a(this.get_class_name(), class_name).unwrap_or(false) {
@ -27,14 +27,14 @@ pub(crate) fn add_class_restricted_getter<'lua, F: LuaUserDataFields<'lua, Insta
} }
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn add_class_restricted_setter<'lua, F: LuaUserDataFields<'lua, Instance>, A, G>( pub(crate) fn add_class_restricted_setter<F: LuaUserDataFields<Instance>, A, G>(
fields: &mut F, fields: &mut F,
class_name: &'static str, class_name: &'static str,
field_name: &'static str, field_name: &'static str,
field_getter: G, field_getter: G,
) where ) where
A: FromLua<'lua>, A: FromLua,
G: 'static + Fn(&'lua Lua, &Instance, A) -> LuaResult<()>, G: 'static + Fn(&Lua, &Instance, A) -> LuaResult<()>,
{ {
fields.add_field_method_set(field_name, move |lua, this, value| { fields.add_field_method_set(field_name, move |lua, this, value| {
if class_is_a(this.get_class_name(), class_name).unwrap_or(false) { if class_is_a(this.get_class_name(), class_name).unwrap_or(false) {
@ -47,15 +47,15 @@ pub(crate) fn add_class_restricted_setter<'lua, F: LuaUserDataFields<'lua, Insta
}); });
} }
pub(crate) fn add_class_restricted_method<'lua, M: LuaUserDataMethods<'lua, Instance>, A, R, F>( pub(crate) fn add_class_restricted_method<M: LuaUserDataMethods<Instance>, A, R, F>(
methods: &mut M, methods: &mut M,
class_name: &'static str, class_name: &'static str,
method_name: &'static str, method_name: &'static str,
method: F, method: F,
) where ) where
A: FromLuaMulti<'lua>, A: FromLuaMulti,
R: IntoLuaMulti<'lua>, R: IntoLuaMulti,
F: 'static + Fn(&'lua Lua, &Instance, A) -> LuaResult<R>, F: 'static + Fn(&Lua, &Instance, A) -> LuaResult<R>,
{ {
methods.add_method(method_name, move |lua, this, args| { methods.add_method(method_name, move |lua, this, args| {
if class_is_a(this.get_class_name(), class_name).unwrap_or(false) { if class_is_a(this.get_class_name(), class_name).unwrap_or(false) {
@ -68,21 +68,15 @@ pub(crate) fn add_class_restricted_method<'lua, M: LuaUserDataMethods<'lua, Inst
}); });
} }
pub(crate) fn add_class_restricted_method_mut< pub(crate) fn add_class_restricted_method_mut<M: LuaUserDataMethods<Instance>, A, R, F>(
'lua,
M: LuaUserDataMethods<'lua, Instance>,
A,
R,
F,
>(
methods: &mut M, methods: &mut M,
class_name: &'static str, class_name: &'static str,
method_name: &'static str, method_name: &'static str,
method: F, method: F,
) where ) where
A: FromLuaMulti<'lua>, A: FromLuaMulti,
R: IntoLuaMulti<'lua>, R: IntoLuaMulti,
F: 'static + Fn(&'lua Lua, &mut Instance, A) -> LuaResult<R>, F: 'static + Fn(&Lua, &mut Instance, A) -> LuaResult<R>,
{ {
methods.add_method_mut(method_name, move |lua, this, args| { methods.add_method_mut(method_name, move |lua, this, args| {
if class_is_a(this.get_class_name(), class_name).unwrap_or(false) { if class_is_a(this.get_class_name(), class_name).unwrap_or(false) {

View file

@ -90,7 +90,7 @@ where
} }
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: rhs.type_name(), from: rhs.type_name(),
to: type_name::<D>(), to: type_name::<D>().to_string(),
message: Some(format!( message: Some(format!(
"Expected {} or number, got {}", "Expected {} or number, got {}",
type_name::<D>(), type_name::<D>(),
@ -115,7 +115,7 @@ where
} }
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: rhs.type_name(), from: rhs.type_name(),
to: type_name::<D>(), to: type_name::<D>().to_string(),
message: Some(format!( message: Some(format!(
"Expected {} or number, got {}", "Expected {} or number, got {}",
type_name::<D>(), type_name::<D>(),
@ -140,7 +140,7 @@ where
} }
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: rhs.type_name(), from: rhs.type_name(),
to: type_name::<D>(), to: type_name::<D>().to_string(),
message: Some(format!( message: Some(format!(
"Expected {} or number, got {}", "Expected {} or number, got {}",
type_name::<D>(), type_name::<D>(),
@ -171,7 +171,7 @@ where
} }
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: rhs.type_name(), from: rhs.type_name(),
to: type_name::<D>(), to: type_name::<D>().to_string(),
message: Some(format!( message: Some(format!(
"Expected {} or number, got {}", "Expected {} or number, got {}",
type_name::<D>(), type_name::<D>(),
@ -196,7 +196,7 @@ where
} }
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: rhs.type_name(), from: rhs.type_name(),
to: type_name::<D>(), to: type_name::<D>().to_string(),
message: Some(format!( message: Some(format!(
"Expected {} or number, got {}", "Expected {} or number, got {}",
type_name::<D>(), type_name::<D>(),

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
thiserror = "1.0" thiserror = "1.0"
chrono = "0.4.38" chrono = "0.4.38"

View file

@ -228,14 +228,14 @@ impl DateTime {
} }
impl LuaUserData for DateTime { impl LuaUserData for DateTime {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("unixTimestamp", |_, this| Ok(this.inner.timestamp())); fields.add_field_method_get("unixTimestamp", |_, this| Ok(this.inner.timestamp()));
fields.add_field_method_get("unixTimestampMillis", |_, this| { fields.add_field_method_get("unixTimestampMillis", |_, this| {
Ok(this.inner.timestamp_millis()) Ok(this.inner.timestamp_millis())
}); });
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
// Metamethods to compare DateTime as instants in time // Metamethods to compare DateTime as instants in time
methods.add_meta_method( methods.add_meta_method(
LuaMetaMethod::Eq, LuaMetaMethod::Eq,

View file

@ -17,7 +17,7 @@ pub use self::date_time::DateTime;
Errors when out of memory. Errors when out of memory.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("fromIsoDate", |_, iso_date: String| { .with_function("fromIsoDate", |_, iso_date: String| {
Ok(DateTime::from_iso_date(iso_date)?) Ok(DateTime::from_iso_date(iso_date)?)

View file

@ -68,12 +68,12 @@ where
a fixed point in time, and we guarantee that it doesn't change a fixed point in time, and we guarantee that it doesn't change
*/ */
impl FromLua<'_> for DateTimeValues { impl FromLua for DateTimeValues {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if !value.is_table() { if !value.is_table() {
return Err(LuaError::FromLuaConversionError { return Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "DateTimeValues", to: "DateTimeValues".to_string(),
message: Some("value must be a table".to_string()), message: Some("value must be a table".to_string()),
}); });
} }
@ -93,16 +93,16 @@ impl FromLua<'_> for DateTimeValues {
Ok(dt) => Ok(dt), Ok(dt) => Ok(dt),
Err(e) => Err(LuaError::FromLuaConversionError { Err(e) => Err(LuaError::FromLuaConversionError {
from: "table", from: "table",
to: "DateTimeValues", to: "DateTimeValues".to_string(),
message: Some(e.to_string()), message: Some(e.to_string()),
}), }),
} }
} }
} }
impl IntoLua<'_> for DateTimeValues { impl IntoLua for DateTimeValues {
fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> { fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
let tab = TableBuilder::new(lua)? let tab = TableBuilder::new(lua.clone())?
.with_value("year", self.year)? .with_value("year", self.year)?
.with_values(vec![ .with_values(vec![
("month", self.month), ("month", self.month),

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
bstr = "1.9" bstr = "1.9"

View file

@ -24,7 +24,7 @@ use self::options::FsWriteOptions;
Errors when out of memory. Errors when out of memory.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_async_function("readFile", fs_read_file)? .with_async_function("readFile", fs_read_file)?
.with_async_function("readDir", fs_read_dir)? .with_async_function("readDir", fs_read_dir)?
@ -40,13 +40,13 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
.build_readonly() .build_readonly()
} }
async fn fs_read_file(lua: &Lua, path: String) -> LuaResult<LuaString> { async fn fs_read_file(lua: Lua, path: String) -> LuaResult<LuaString> {
let bytes = fs::read(&path).await.into_lua_err()?; let bytes = fs::read(&path).await.into_lua_err()?;
lua.create_string(bytes) lua.create_string(bytes)
} }
async fn fs_read_dir(_: &Lua, path: String) -> LuaResult<Vec<String>> { async fn fs_read_dir(_: Lua, path: String) -> LuaResult<Vec<String>> {
let mut dir_strings = Vec::new(); let mut dir_strings = Vec::new();
let mut dir = fs::read_dir(&path).await.into_lua_err()?; let mut dir = fs::read_dir(&path).await.into_lua_err()?;
while let Some(dir_entry) = dir.next_entry().await.into_lua_err()? { while let Some(dir_entry) = dir.next_entry().await.into_lua_err()? {
@ -62,23 +62,23 @@ async fn fs_read_dir(_: &Lua, path: String) -> LuaResult<Vec<String>> {
Ok(dir_strings) Ok(dir_strings)
} }
async fn fs_write_file(_: &Lua, (path, contents): (String, BString)) -> LuaResult<()> { async fn fs_write_file(_: Lua, (path, contents): (String, BString)) -> LuaResult<()> {
fs::write(&path, contents.as_bytes()).await.into_lua_err() fs::write(&path, contents.as_bytes()).await.into_lua_err()
} }
async fn fs_write_dir(_: &Lua, path: String) -> LuaResult<()> { async fn fs_write_dir(_: Lua, path: String) -> LuaResult<()> {
fs::create_dir_all(&path).await.into_lua_err() fs::create_dir_all(&path).await.into_lua_err()
} }
async fn fs_remove_file(_: &Lua, path: String) -> LuaResult<()> { async fn fs_remove_file(_: Lua, path: String) -> LuaResult<()> {
fs::remove_file(&path).await.into_lua_err() fs::remove_file(&path).await.into_lua_err()
} }
async fn fs_remove_dir(_: &Lua, path: String) -> LuaResult<()> { async fn fs_remove_dir(_: Lua, path: String) -> LuaResult<()> {
fs::remove_dir_all(&path).await.into_lua_err() fs::remove_dir_all(&path).await.into_lua_err()
} }
async fn fs_metadata(_: &Lua, path: String) -> LuaResult<FsMetadata> { async fn fs_metadata(_: Lua, path: String) -> LuaResult<FsMetadata> {
match fs::metadata(path).await { match fs::metadata(path).await {
Err(e) if e.kind() == IoErrorKind::NotFound => Ok(FsMetadata::not_found()), Err(e) if e.kind() == IoErrorKind::NotFound => Ok(FsMetadata::not_found()),
Ok(meta) => Ok(FsMetadata::from(meta)), Ok(meta) => Ok(FsMetadata::from(meta)),
@ -86,7 +86,7 @@ async fn fs_metadata(_: &Lua, path: String) -> LuaResult<FsMetadata> {
} }
} }
async fn fs_is_file(_: &Lua, path: String) -> LuaResult<bool> { async fn fs_is_file(_: Lua, path: String) -> LuaResult<bool> {
match fs::metadata(path).await { match fs::metadata(path).await {
Err(e) if e.kind() == IoErrorKind::NotFound => Ok(false), Err(e) if e.kind() == IoErrorKind::NotFound => Ok(false),
Ok(meta) => Ok(meta.is_file()), Ok(meta) => Ok(meta.is_file()),
@ -94,7 +94,7 @@ async fn fs_is_file(_: &Lua, path: String) -> LuaResult<bool> {
} }
} }
async fn fs_is_dir(_: &Lua, path: String) -> LuaResult<bool> { async fn fs_is_dir(_: Lua, path: String) -> LuaResult<bool> {
match fs::metadata(path).await { match fs::metadata(path).await {
Err(e) if e.kind() == IoErrorKind::NotFound => Ok(false), Err(e) if e.kind() == IoErrorKind::NotFound => Ok(false),
Ok(meta) => Ok(meta.is_dir()), Ok(meta) => Ok(meta.is_dir()),
@ -102,7 +102,7 @@ async fn fs_is_dir(_: &Lua, path: String) -> LuaResult<bool> {
} }
} }
async fn fs_move(_: &Lua, (from, to, options): (String, String, FsWriteOptions)) -> LuaResult<()> { async fn fs_move(_: Lua, (from, to, options): (String, String, FsWriteOptions)) -> LuaResult<()> {
let path_from = PathBuf::from(from); let path_from = PathBuf::from(from);
if !path_from.exists() { if !path_from.exists() {
return Err(LuaError::RuntimeError(format!( return Err(LuaError::RuntimeError(format!(
@ -121,6 +121,6 @@ async fn fs_move(_: &Lua, (from, to, options): (String, String, FsWriteOptions))
Ok(()) Ok(())
} }
async fn fs_copy(_: &Lua, (from, to, options): (String, String, FsWriteOptions)) -> LuaResult<()> { async fn fs_copy(_: Lua, (from, to, options): (String, String, FsWriteOptions)) -> LuaResult<()> {
copy(from, to, options).await copy(from, to, options).await
} }

View file

@ -61,8 +61,8 @@ impl From<StdFileType> for FsMetadataKind {
} }
} }
impl<'lua> IntoLua<'lua> for FsMetadataKind { impl IntoLua for FsMetadataKind {
fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
if self == Self::None { if self == Self::None {
Ok(LuaValue::Nil) Ok(LuaValue::Nil)
} else { } else {
@ -84,8 +84,8 @@ impl From<StdPermissions> for FsPermissions {
} }
} }
impl<'lua> IntoLua<'lua> for FsPermissions { impl IntoLua for FsPermissions {
fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
let tab = lua.create_table_with_capacity(0, 1)?; let tab = lua.create_table_with_capacity(0, 1)?;
tab.set("readOnly", self.read_only)?; tab.set("readOnly", self.read_only)?;
tab.set_readonly(true); tab.set_readonly(true);
@ -116,8 +116,8 @@ impl FsMetadata {
} }
} }
impl<'lua> IntoLua<'lua> for FsMetadata { impl IntoLua for FsMetadata {
fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
let tab = lua.create_table_with_capacity(0, 6)?; let tab = lua.create_table_with_capacity(0, 6)?;
tab.set("kind", self.kind)?; tab.set("kind", self.kind)?;
tab.set("exists", self.exists)?; tab.set("exists", self.exists)?;

View file

@ -5,8 +5,8 @@ pub struct FsWriteOptions {
pub(crate) overwrite: bool, pub(crate) overwrite: bool,
} }
impl<'lua> FromLua<'lua> for FsWriteOptions { impl FromLua for FsWriteOptions {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
Ok(match value { Ok(match value {
LuaValue::Nil => Self { overwrite: false }, LuaValue::Nil => Self { overwrite: false },
LuaValue::Boolean(b) => Self { overwrite: b }, LuaValue::Boolean(b) => Self { overwrite: b },
@ -19,7 +19,7 @@ impl<'lua> FromLua<'lua> for FsWriteOptions {
_ => { _ => {
return Err(LuaError::FromLuaConversionError { return Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "FsWriteOptions", to: "FsWriteOptions".to_string(),
message: Some(format!( message: Some(format!(
"Invalid write options - expected boolean or table, got {}", "Invalid write options - expected boolean or table, got {}",
value.type_name() value.type_name()

View file

@ -13,6 +13,6 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau", "luau-jit"] } mlua = { version = "0.10.3", features = ["luau", "luau-jit"] }
lune-utils = { version = "0.1.3", path = "../lune-utils" } lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -2,14 +2,12 @@
use mlua::prelude::*; use mlua::prelude::*;
use lune_utils::{jit::JitStatus, TableBuilder}; use lune_utils::{jit::JitEnablement, TableBuilder};
mod options; mod options;
use self::options::{LuauCompileOptions, LuauLoadOptions}; use self::options::{LuauCompileOptions, LuauLoadOptions};
const BYTECODE_ERROR_BYTE: u8 = 0;
/** /**
Creates the `luau` standard library module. Creates the `luau` standard library module.
@ -17,33 +15,30 @@ const BYTECODE_ERROR_BYTE: u8 = 0;
Errors when out of memory. Errors when out of memory.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("compile", compile_source)? .with_function("compile", compile_source)?
.with_function("load", load_source)? .with_function("load", load_source)?
.build_readonly() .build_readonly()
} }
fn compile_source<'lua>( fn compile_source(
lua: &'lua Lua, lua: &Lua,
(source, options): (LuaString<'lua>, LuauCompileOptions), (source, options): (LuaString, LuauCompileOptions),
) -> LuaResult<LuaString<'lua>> { ) -> LuaResult<LuaString> {
let bytecode = options.into_compiler().compile(source); options
.into_compiler()
match bytecode.first() { .compile(source.as_bytes())
Some(&BYTECODE_ERROR_BYTE) => Err(LuaError::RuntimeError( .and_then(|s| lua.create_string(s))
String::from_utf8_lossy(&bytecode).into_owned(),
)),
Some(_) => lua.create_string(bytecode),
None => panic!("Compiling resulted in empty bytecode"),
}
} }
fn load_source<'lua>( fn load_source(
lua: &'lua Lua, lua: &Lua,
(source, options): (LuaString<'lua>, LuauLoadOptions), (source, options): (LuaString, LuauLoadOptions),
) -> LuaResult<LuaFunction<'lua>> { ) -> LuaResult<LuaFunction> {
let mut chunk = lua.load(source.as_bytes()).set_name(options.debug_name); let mut chunk = lua
.load(source.as_bytes().to_vec())
.set_name(options.debug_name);
let env_changed = options.environment.is_some(); let env_changed = options.environment.is_some();
if let Some(custom_environment) = options.environment { if let Some(custom_environment) = options.environment {
@ -56,10 +51,10 @@ fn load_source<'lua>(
environment.set(key, value)?; environment.set(key, value)?;
} }
if let Some(global_metatable) = lua.globals().get_metatable() { if let Some(global_metatable) = lua.globals().metatable() {
environment.set_metatable(Some(global_metatable)); environment.set_metatable(Some(global_metatable));
} }
} else if let Some(custom_metatable) = custom_environment.get_metatable() { } else if let Some(custom_metatable) = custom_environment.metatable() {
// Since we don't need to set the global metatable, // Since we don't need to set the global metatable,
// we can just set a custom metatable if it exists // we can just set a custom metatable if it exists
environment.set_metatable(Some(custom_metatable)); environment.set_metatable(Some(custom_metatable));
@ -79,7 +74,7 @@ fn load_source<'lua>(
lua.enable_jit(options.codegen_enabled && !env_changed); lua.enable_jit(options.codegen_enabled && !env_changed);
let function = chunk.into_function()?; let function = chunk.into_function()?;
lua.enable_jit( lua.enable_jit(
lua.app_data_ref::<JitStatus>() lua.app_data_ref::<JitEnablement>()
.ok_or(LuaError::runtime( .ok_or(LuaError::runtime(
"Failed to get current JitStatus ref from AppData", "Failed to get current JitStatus ref from AppData",
))? ))?

View file

@ -36,8 +36,8 @@ impl Default for LuauCompileOptions {
} }
} }
impl<'lua> FromLua<'lua> for LuauCompileOptions { impl FromLua for LuauCompileOptions {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
Ok(match value { Ok(match value {
LuaValue::Nil => Self::default(), LuaValue::Nil => Self::default(),
LuaValue::Table(t) => { LuaValue::Table(t) => {
@ -68,7 +68,7 @@ impl<'lua> FromLua<'lua> for LuauCompileOptions {
_ => { _ => {
return Err(LuaError::FromLuaConversionError { return Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "CompileOptions", to: "CompileOptions".to_string(),
message: Some(format!( message: Some(format!(
"Invalid compile options - expected table, got {}", "Invalid compile options - expected table, got {}",
value.type_name() value.type_name()
@ -79,14 +79,14 @@ impl<'lua> FromLua<'lua> for LuauCompileOptions {
} }
} }
pub struct LuauLoadOptions<'lua> { pub struct LuauLoadOptions {
pub(crate) debug_name: String, pub(crate) debug_name: String,
pub(crate) environment: Option<LuaTable<'lua>>, pub(crate) environment: Option<LuaTable>,
pub(crate) inject_globals: bool, pub(crate) inject_globals: bool,
pub(crate) codegen_enabled: bool, pub(crate) codegen_enabled: bool,
} }
impl Default for LuauLoadOptions<'_> { impl Default for LuauLoadOptions {
fn default() -> Self { fn default() -> Self {
Self { Self {
debug_name: DEFAULT_DEBUG_NAME.to_string(), debug_name: DEFAULT_DEBUG_NAME.to_string(),
@ -97,8 +97,8 @@ impl Default for LuauLoadOptions<'_> {
} }
} }
impl<'lua> FromLua<'lua> for LuauLoadOptions<'lua> { impl FromLua for LuauLoadOptions {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
Ok(match value { Ok(match value {
LuaValue::Nil => Self::default(), LuaValue::Nil => Self::default(),
LuaValue::Table(t) => { LuaValue::Table(t) => {
@ -131,7 +131,7 @@ impl<'lua> FromLua<'lua> for LuauLoadOptions<'lua> {
_ => { _ => {
return Err(LuaError::FromLuaConversionError { return Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "LoadOptions", to: "LoadOptions".to_string(),
message: Some(format!( message: Some(format!(
"Invalid load options - expected string or table, got {}", "Invalid load options - expected string or table, got {}",
value.type_name() value.type_name()

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" } mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
bstr = "1.9" bstr = "1.9"

View file

@ -119,7 +119,7 @@ impl NetClient {
impl LuaUserData for NetClient {} impl LuaUserData for NetClient {}
impl FromLua<'_> for NetClient { impl FromLua for NetClient {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::UserData(ud) = value { if let LuaValue::UserData(ud) = value {
if let Ok(ctx) = ud.borrow::<NetClient>() { if let Ok(ctx) = ud.borrow::<NetClient>() {
@ -149,7 +149,7 @@ pub struct NetClientResponse {
impl NetClientResponse { impl NetClientResponse {
pub fn into_lua_table(self, lua: &Lua) -> LuaResult<LuaTable> { pub fn into_lua_table(self, lua: &Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)? TableBuilder::new(lua.clone())?
.with_value("ok", self.ok)? .with_value("ok", self.ok)?
.with_value("statusCode", self.status_code)? .with_value("statusCode", self.status_code)?
.with_value("statusMessage", self.status_message)? .with_value("statusMessage", self.status_message)?

View file

@ -35,14 +35,14 @@ impl Default for RequestConfigOptions {
} }
} }
impl<'lua> FromLua<'lua> for RequestConfigOptions { impl FromLua for RequestConfigOptions {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::Nil = value { if let LuaValue::Nil = value {
// Nil means default options // Nil means default options
Ok(Self::default()) Ok(Self::default())
} else if let LuaValue::Table(tab) = value { } else if let LuaValue::Table(tab) = value {
// Table means custom options // Table means custom options
let decompress = match tab.get::<_, Option<bool>>("decompress") { let decompress = match tab.get::<Option<bool>>("decompress") {
Ok(decomp) => Ok(decomp.unwrap_or(true)), Ok(decomp) => Ok(decomp.unwrap_or(true)),
Err(_) => Err(LuaError::RuntimeError( Err(_) => Err(LuaError::RuntimeError(
"Invalid option value for 'decompress' in request config options".to_string(), "Invalid option value for 'decompress' in request config options".to_string(),
@ -53,7 +53,7 @@ impl<'lua> FromLua<'lua> for RequestConfigOptions {
// Anything else is invalid // Anything else is invalid
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "RequestConfigOptions", to: "RequestConfigOptions".to_string(),
message: Some(format!( message: Some(format!(
"Invalid request config options - expected table or nil, got {}", "Invalid request config options - expected table or nil, got {}",
value.type_name() value.type_name()
@ -73,7 +73,7 @@ pub struct RequestConfig {
pub options: RequestConfigOptions, pub options: RequestConfigOptions,
} }
impl FromLua<'_> for RequestConfig { impl FromLua for RequestConfig {
fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
// If we just got a string we assume its a GET request to a given url // If we just got a string we assume its a GET request to a given url
if let LuaValue::String(s) = value { if let LuaValue::String(s) = value {
@ -88,27 +88,27 @@ impl FromLua<'_> for RequestConfig {
} else if let LuaValue::Table(tab) = value { } else if let LuaValue::Table(tab) = value {
// If we got a table we are able to configure the entire request // If we got a table we are able to configure the entire request
// Extract url // Extract url
let url = match tab.get::<_, LuaString>("url") { let url = match tab.get::<LuaString>("url") {
Ok(config_url) => Ok(config_url.to_string_lossy().to_string()), Ok(config_url) => Ok(config_url.to_string_lossy().to_string()),
Err(_) => Err(LuaError::runtime("Missing 'url' in request config")), Err(_) => Err(LuaError::runtime("Missing 'url' in request config")),
}?; }?;
// Extract method // Extract method
let method = match tab.get::<_, LuaString>("method") { let method = match tab.get::<LuaString>("method") {
Ok(config_method) => config_method.to_string_lossy().trim().to_ascii_uppercase(), Ok(config_method) => config_method.to_string_lossy().trim().to_ascii_uppercase(),
Err(_) => "GET".to_string(), Err(_) => "GET".to_string(),
}; };
// Extract query // Extract query
let query = match tab.get::<_, LuaTable>("query") { let query = match tab.get::<LuaTable>("query") {
Ok(tab) => table_to_hash_map(tab, "query")?, Ok(tab) => table_to_hash_map(tab, "query")?,
Err(_) => HashMap::new(), Err(_) => HashMap::new(),
}; };
// Extract headers // Extract headers
let headers = match tab.get::<_, LuaTable>("headers") { let headers = match tab.get::<LuaTable>("headers") {
Ok(tab) => table_to_hash_map(tab, "headers")?, Ok(tab) => table_to_hash_map(tab, "headers")?,
Err(_) => HashMap::new(), Err(_) => HashMap::new(),
}; };
// Extract body // Extract body
let body = match tab.get::<_, BString>("body") { let body = match tab.get::<BString>("body") {
Ok(config_body) => Some(config_body.as_bytes().to_owned()), Ok(config_body) => Some(config_body.as_bytes().to_owned()),
Err(_) => None, Err(_) => None,
}; };
@ -129,7 +129,7 @@ impl FromLua<'_> for RequestConfig {
))), ))),
}?; }?;
// Parse any extra options given // Parse any extra options given
let options = match tab.get::<_, LuaValue>("options") { let options = match tab.get::<LuaValue>("options") {
Ok(opts) => RequestConfigOptions::from_lua(opts, lua)?, Ok(opts) => RequestConfigOptions::from_lua(opts, lua)?,
Err(_) => RequestConfigOptions::default(), Err(_) => RequestConfigOptions::default(),
}; };
@ -146,7 +146,7 @@ impl FromLua<'_> for RequestConfig {
// Anything else is invalid // Anything else is invalid
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "RequestConfig", to: "RequestConfig".to_string(),
message: Some(format!( message: Some(format!(
"Invalid request config - expected string or table, got {}", "Invalid request config - expected string or table, got {}",
value.type_name() value.type_name()
@ -159,14 +159,14 @@ impl FromLua<'_> for RequestConfig {
// Net serve config // Net serve config
#[derive(Debug)] #[derive(Debug)]
pub struct ServeConfig<'a> { pub struct ServeConfig {
pub address: IpAddr, pub address: IpAddr,
pub handle_request: LuaFunction<'a>, pub handle_request: LuaFunction,
pub handle_web_socket: Option<LuaFunction<'a>>, pub handle_web_socket: Option<LuaFunction>,
} }
impl<'lua> FromLua<'lua> for ServeConfig<'lua> { impl FromLua for ServeConfig {
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
if let LuaValue::Function(f) = &value { if let LuaValue::Function(f) = &value {
// Single function = request handler, rest is default // Single function = request handler, rest is default
Ok(ServeConfig { Ok(ServeConfig {
@ -190,7 +190,7 @@ impl<'lua> FromLua<'lua> for ServeConfig<'lua> {
.parse() .parse()
.map_err(|_e| LuaError::FromLuaConversionError { .map_err(|_e| LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "ServeConfig", to: "ServeConfig".to_string(),
message: Some(format!( message: Some(format!(
"IP address format is incorrect - \ "IP address format is incorrect - \
expected an IP in the form 'http://0.0.0.0' or '0.0.0.0', \ expected an IP in the form 'http://0.0.0.0' or '0.0.0.0', \
@ -213,7 +213,7 @@ impl<'lua> FromLua<'lua> for ServeConfig<'lua> {
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "ServeConfig", to: "ServeConfig".to_string(),
message: Some(String::from( message: Some(String::from(
"Invalid serve config - expected table with 'handleRequest' or 'handleWebSocket' function", "Invalid serve config - expected table with 'handleRequest' or 'handleWebSocket' function",
)), )),
@ -223,7 +223,7 @@ impl<'lua> FromLua<'lua> for ServeConfig<'lua> {
// Anything else is invalid // Anything else is invalid
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "ServeConfig", to: "ServeConfig".to_string(),
message: None, message: None,
}) })
} }

View file

@ -29,11 +29,11 @@ use lune_std_serde::{decode, encode, EncodeDecodeConfig, EncodeDecodeFormat};
Errors when out of memory. Errors when out of memory.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
NetClientBuilder::new() NetClientBuilder::new()
.headers(&[("User-Agent", create_user_agent_header(lua)?)])? .headers(&[("User-Agent", create_user_agent_header(&lua)?)])?
.build()? .build()?
.into_registry(lua); .into_registry(&lua);
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("jsonEncode", net_json_encode)? .with_function("jsonEncode", net_json_encode)?
.with_function("jsonDecode", net_json_decode)? .with_function("jsonDecode", net_json_decode)?
@ -45,10 +45,7 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
.build_readonly() .build_readonly()
} }
fn net_json_encode<'lua>( fn net_json_encode(lua: &Lua, (val, pretty): (LuaValue, Option<bool>)) -> LuaResult<LuaString> {
lua: &'lua Lua,
(val, pretty): (LuaValue<'lua>, Option<bool>),
) -> LuaResult<LuaString<'lua>> {
let config = EncodeDecodeConfig::from((EncodeDecodeFormat::Json, pretty.unwrap_or_default())); let config = EncodeDecodeConfig::from((EncodeDecodeFormat::Json, pretty.unwrap_or_default()));
encode(val, lua, config) encode(val, lua, config)
} }
@ -58,44 +55,41 @@ fn net_json_decode(lua: &Lua, json: BString) -> LuaResult<LuaValue> {
decode(json, lua, config) decode(json, lua, config)
} }
async fn net_request(lua: &Lua, config: RequestConfig) -> LuaResult<LuaTable> { async fn net_request(lua: Lua, config: RequestConfig) -> LuaResult<LuaTable> {
let client = NetClient::from_registry(lua); let client = NetClient::from_registry(&lua);
// NOTE: We spawn the request as a background task to free up resources in lua // NOTE: We spawn the request as a background task to free up resources in lua
let res = lua.spawn(async move { client.request(config).await }); let res = lua.spawn(async move { client.request(config).await });
res.await?.into_lua_table(lua) res.await?.into_lua_table(&lua)
} }
async fn net_socket(lua: &Lua, url: String) -> LuaResult<LuaValue> { async fn net_socket(lua: Lua, url: String) -> LuaResult<LuaValue> {
let (ws, _) = tokio_tungstenite::connect_async(url).await.into_lua_err()?; let (ws, _) = tokio_tungstenite::connect_async(url).await.into_lua_err()?;
NetWebSocket::new(ws).into_lua(lua) NetWebSocket::new(ws).into_lua(&lua)
} }
async fn net_serve<'lua>( async fn net_serve(lua: Lua, (port, config): (u16, ServeConfig)) -> LuaResult<LuaTable> {
lua: &'lua Lua,
(port, config): (u16, ServeConfig<'lua>),
) -> LuaResult<LuaTable<'lua>> {
serve(lua, port, config).await serve(lua, port, config).await
} }
fn net_url_encode<'lua>( fn net_url_encode(
lua: &'lua Lua, lua: &Lua,
(lua_string, as_binary): (LuaString<'lua>, Option<bool>), (lua_string, as_binary): (LuaString, Option<bool>),
) -> LuaResult<LuaValue<'lua>> { ) -> LuaResult<LuaValue> {
if matches!(as_binary, Some(true)) { if matches!(as_binary, Some(true)) {
urlencoding::encode_binary(lua_string.as_bytes()).into_lua(lua) urlencoding::encode_binary(&lua_string.as_bytes()).into_lua(lua)
} else { } else {
urlencoding::encode(lua_string.to_str()?).into_lua(lua) urlencoding::encode(&lua_string.to_str()?).into_lua(lua)
} }
} }
fn net_url_decode<'lua>( fn net_url_decode(
lua: &'lua Lua, lua: &Lua,
(lua_string, as_binary): (LuaString<'lua>, Option<bool>), (lua_string, as_binary): (LuaString, Option<bool>),
) -> LuaResult<LuaValue<'lua>> { ) -> LuaResult<LuaValue> {
if matches!(as_binary, Some(true)) { if matches!(as_binary, Some(true)) {
urlencoding::decode_binary(lua_string.as_bytes()).into_lua(lua) urlencoding::decode_binary(&lua_string.as_bytes()).into_lua(lua)
} else { } else {
urlencoding::decode(lua_string.to_str()?) urlencoding::decode(&lua_string.to_str()?)
.map_err(|e| LuaError::RuntimeError(format!("Encountered invalid encoding - {e}")))? .map_err(|e| LuaError::RuntimeError(format!("Encountered invalid encoding - {e}")))?
.into_lua(lua) .into_lua(lua)
} }

View file

@ -9,10 +9,10 @@ pub(super) struct SvcKeys {
} }
impl SvcKeys { impl SvcKeys {
pub(super) fn new<'lua>( pub(super) fn new(
lua: &'lua Lua, lua: Lua,
handle_request: LuaFunction<'lua>, handle_request: LuaFunction,
handle_websocket: Option<LuaFunction<'lua>>, handle_websocket: Option<LuaFunction>,
) -> LuaResult<Self> { ) -> LuaResult<Self> {
static SERVE_COUNTER: AtomicUsize = AtomicUsize::new(0); static SERVE_COUNTER: AtomicUsize = AtomicUsize::new(0);
let count = SERVE_COUNTER.fetch_add(1, Ordering::Relaxed); let count = SERVE_COUNTER.fetch_add(1, Ordering::Relaxed);
@ -46,14 +46,11 @@ impl SvcKeys {
self.key_websocket.is_some() self.key_websocket.is_some()
} }
pub(super) fn request_handler<'lua>(&self, lua: &'lua Lua) -> LuaResult<LuaFunction<'lua>> { pub(super) fn request_handler(&self, lua: &Lua) -> LuaResult<LuaFunction> {
lua.named_registry_value(self.key_request) lua.named_registry_value(self.key_request)
} }
pub(super) fn websocket_handler<'lua>( pub(super) fn websocket_handler(&self, lua: &Lua) -> LuaResult<Option<LuaFunction>> {
&self,
lua: &'lua Lua,
) -> LuaResult<Option<LuaFunction<'lua>>> {
self.key_websocket self.key_websocket
.map(|key| lua.named_registry_value(key)) .map(|key| lua.named_registry_value(key))
.transpose() .transpose()

View file

@ -1,7 +1,4 @@
use std::{ use std::net::SocketAddr;
net::SocketAddr,
rc::{Rc, Weak},
};
use hyper::server::conn::http1; use hyper::server::conn::http1;
use hyper_util::rt::TokioIo; use hyper_util::rt::TokioIo;
@ -22,24 +19,14 @@ mod service;
use keys::SvcKeys; use keys::SvcKeys;
use service::Svc; use service::Svc;
pub async fn serve<'lua>( pub async fn serve(lua: Lua, port: u16, config: ServeConfig) -> LuaResult<LuaTable> {
lua: &'lua Lua,
port: u16,
config: ServeConfig<'lua>,
) -> LuaResult<LuaTable<'lua>> {
let addr: SocketAddr = (config.address, port).into(); let addr: SocketAddr = (config.address, port).into();
let listener = TcpListener::bind(addr).await?; let listener = TcpListener::bind(addr).await?;
let (lua_svc, lua_inner) = { let lua_svc = lua.clone();
let rc = lua let lua_inner = lua.clone();
.app_data_ref::<Weak<Lua>>()
.expect("Missing weak lua ref")
.upgrade()
.expect("Lua was dropped unexpectedly");
(Rc::clone(&rc), rc)
};
let keys = SvcKeys::new(lua, config.handle_request, config.handle_web_socket)?; let keys = SvcKeys::new(lua.clone(), config.handle_request, config.handle_web_socket)?;
let svc = Svc { let svc = Svc {
lua: lua_svc, lua: lua_svc,
addr, addr,

View file

@ -45,7 +45,7 @@ impl LuaRequest {
}) })
.collect::<LuaResult<_>>()?; .collect::<LuaResult<_>>()?;
TableBuilder::new(lua)? TableBuilder::new(lua.clone())?
.with_value("method", method)? .with_value("method", method)?
.with_value("path", path)? .with_value("path", path)?
.with_value("query", query)? .with_value("query", query)?

View file

@ -43,7 +43,7 @@ impl LuaResponse {
} }
} }
impl FromLua<'_> for LuaResponse { impl FromLua for LuaResponse {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
match value { match value {
// Plain strings from the handler are plaintext responses // Plain strings from the handler are plaintext responses
@ -64,7 +64,7 @@ impl FromLua<'_> for LuaResponse {
for pair in headers.pairs::<String, LuaString>() { for pair in headers.pairs::<String, LuaString>() {
let (h, v) = pair?; let (h, v) = pair?;
let name = HeaderName::from_str(&h).into_lua_err()?; let name = HeaderName::from_str(&h).into_lua_err()?;
let value = HeaderValue::from_bytes(v.as_bytes()).into_lua_err()?; let value = HeaderValue::from_bytes(&v.as_bytes()).into_lua_err()?;
headers_map.insert(name, value); headers_map.insert(name, value);
} }
} }
@ -81,7 +81,7 @@ impl FromLua<'_> for LuaResponse {
// Anything else is an error // Anything else is an error
value => Err(LuaError::FromLuaConversionError { value => Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "NetServeResponse", to: "NetServeResponse".to_string(),
message: None, message: None,
}), }),
} }

View file

@ -1,4 +1,4 @@
use std::{future::Future, net::SocketAddr, pin::Pin, rc::Rc}; use std::{future::Future, net::SocketAddr, pin::Pin};
use http_body_util::{BodyExt, Full}; use http_body_util::{BodyExt, Full};
use hyper::{ use hyper::{
@ -17,7 +17,7 @@ use super::{
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(super) struct Svc { pub(super) struct Svc {
pub(super) lua: Rc<Lua>, pub(super) lua: Lua,
pub(super) addr: SocketAddr, pub(super) addr: SocketAddr,
pub(super) keys: SvcKeys, pub(super) keys: SvcKeys,
} }

View file

@ -10,7 +10,7 @@ use lune_utils::TableBuilder;
pub fn create_user_agent_header(lua: &Lua) -> LuaResult<String> { pub fn create_user_agent_header(lua: &Lua) -> LuaResult<String> {
let version_global = lua let version_global = lua
.globals() .globals()
.get::<_, LuaString>("_VERSION") .get::<LuaString>("_VERSION")
.expect("Missing _VERSION global"); .expect("Missing _VERSION global");
let version_global_str = version_global let version_global_str = version_global
@ -46,13 +46,13 @@ pub fn header_map_to_table(
}); });
} }
let mut builder = TableBuilder::new(lua)?; let mut builder = TableBuilder::new(lua.clone())?;
for (name, mut values) in res_headers { for (name, mut values) in res_headers {
if values.len() == 1 { if values.len() == 1 {
let value = values.pop().unwrap().into_lua(lua)?; let value = values.pop().unwrap().into_lua(lua)?;
builder = builder.with_value(name, value)?; builder = builder.with_value(name, value)?;
} else { } else {
let values = TableBuilder::new(lua)? let values = TableBuilder::new(lua.clone())?
.with_sequential_values(values)? .with_sequential_values(values)?
.build_readonly()? .build_readonly()?
.into_lua(lua)?; .into_lua(lua)?;

View file

@ -108,11 +108,11 @@ impl<T> LuaUserData for NetWebSocket<T>
where where
T: AsyncRead + AsyncWrite + Unpin + 'static, T: AsyncRead + AsyncWrite + Unpin + 'static,
{ {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("closeCode", |_, this| Ok(this.get_close_code())); fields.add_field_method_get("closeCode", |_, this| Ok(this.get_close_code()));
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_async_method("close", |_, this, code: Option<u16>| async move { methods.add_async_method("close", |_, this, code: Option<u16>| async move {
this.close(code).await this.close(code).await
}); });

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" } mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
directories = "5.0" directories = "5.0"

View file

@ -39,7 +39,7 @@ use lune_utils::path::get_current_dir;
Errors when out of memory. Errors when out of memory.
*/ */
#[allow(clippy::missing_panics_doc)] #[allow(clippy::missing_panics_doc)]
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
let mut cwd_str = get_current_dir() let mut cwd_str = get_current_dir()
.to_str() .to_str()
.expect("cwd should be valid UTF-8") .expect("cwd should be valid UTF-8")
@ -60,13 +60,13 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
.app_data_ref::<Vec<String>>() .app_data_ref::<Vec<String>>()
.ok_or_else(|| LuaError::runtime("Missing args vec in Lua app data"))? .ok_or_else(|| LuaError::runtime("Missing args vec in Lua app data"))?
.clone(); .clone();
let args_tab = TableBuilder::new(lua)? let args_tab = TableBuilder::new(lua.clone())?
.with_sequential_values(args_vec)? .with_sequential_values(args_vec)?
.build_readonly()?; .build_readonly()?;
// Create proxied table for env that gets & sets real env vars // Create proxied table for env that gets & sets real env vars
let env_tab = TableBuilder::new(lua)? let env_tab = TableBuilder::new(lua.clone())?
.with_metatable( .with_metatable(
TableBuilder::new(lua)? TableBuilder::new(lua.clone())?
.with_function(LuaMetaMethod::Index.name(), process_env_get)? .with_function(LuaMetaMethod::Index.name(), process_env_get)?
.with_function(LuaMetaMethod::NewIndex.name(), process_env_set)? .with_function(LuaMetaMethod::NewIndex.name(), process_env_set)?
.with_function(LuaMetaMethod::Iter.name(), process_env_iter)? .with_function(LuaMetaMethod::Iter.name(), process_env_iter)?
@ -74,7 +74,7 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
)? )?
.build_readonly()?; .build_readonly()?;
// Create our process exit function, the scheduler crate provides this // Create our process exit function, the scheduler crate provides this
let fns = Functions::new(lua)?; let fns = Functions::new(lua.clone())?;
let process_exit = fns.exit; let process_exit = fns.exit;
// Create the full process table // Create the full process table
TableBuilder::new(lua)? TableBuilder::new(lua)?
@ -90,10 +90,7 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
.build_readonly() .build_readonly()
} }
fn process_env_get<'lua>( fn process_env_get(lua: &Lua, (_, key): (LuaValue, String)) -> LuaResult<LuaValue> {
lua: &'lua Lua,
(_, key): (LuaValue<'lua>, String),
) -> LuaResult<LuaValue<'lua>> {
match env::var_os(key) { match env::var_os(key) {
Some(value) => { Some(value) => {
let raw_value = RawOsString::new(value); let raw_value = RawOsString::new(value);
@ -105,10 +102,7 @@ fn process_env_get<'lua>(
} }
} }
fn process_env_set<'lua>( fn process_env_set(_: &Lua, (_, key, value): (LuaValue, String, Option<String>)) -> LuaResult<()> {
_: &'lua Lua,
(_, key, value): (LuaValue<'lua>, String, Option<String>),
) -> LuaResult<()> {
// Make sure key is valid, otherwise set_var will panic // Make sure key is valid, otherwise set_var will panic
if key.is_empty() { if key.is_empty() {
Err(LuaError::RuntimeError("Key must not be empty".to_string())) Err(LuaError::RuntimeError("Key must not be empty".to_string()))
@ -136,10 +130,7 @@ fn process_env_set<'lua>(
} }
} }
fn process_env_iter<'lua>( fn process_env_iter(lua: &Lua, (_, ()): (LuaValue, ())) -> LuaResult<LuaFunction> {
lua: &'lua Lua,
(_, ()): (LuaValue<'lua>, ()),
) -> LuaResult<LuaFunction<'lua>> {
let mut vars = env::vars_os().collect::<Vec<_>>().into_iter(); let mut vars = env::vars_os().collect::<Vec<_>>().into_iter();
lua.create_function_mut(move |lua, (): ()| match vars.next() { lua.create_function_mut(move |lua, (): ()| match vars.next() {
Some((key, value)) => { Some((key, value)) => {
@ -155,7 +146,7 @@ fn process_env_iter<'lua>(
} }
async fn process_exec( async fn process_exec(
lua: &Lua, lua: Lua,
(program, args, options): (String, Option<Vec<String>>, ProcessSpawnOptions), (program, args, options): (String, Option<Vec<String>>, ProcessSpawnOptions),
) -> LuaResult<LuaTable> { ) -> LuaResult<LuaTable> {
let res = lua let res = lua
@ -178,7 +169,7 @@ async fn process_exec(
.unwrap_or(i32::from(!res.stderr.is_empty())); .unwrap_or(i32::from(!res.stderr.is_empty()));
// Construct and return a readonly lua table with results // Construct and return a readonly lua table with results
TableBuilder::new(lua)? TableBuilder::new(lua.clone())?
.with_value("ok", code == 0)? .with_value("ok", code == 0)?
.with_value("code", code)? .with_value("code", code)?
.with_value("stdout", lua.create_string(&res.stdout)?)? .with_value("stdout", lua.create_string(&res.stdout)?)?
@ -225,7 +216,7 @@ fn process_create(
} }
}); });
TableBuilder::new(lua)? TableBuilder::new(lua.clone())?
.with_value("stdout", ChildProcessReader(stdout))? .with_value("stdout", ChildProcessReader(stdout))?
.with_value("stderr", ChildProcessReader(stderr))? .with_value("stderr", ChildProcessReader(stderr))?
.with_value("stdin", ChildProcessWriter(stdin))? .with_value("stdin", ChildProcessWriter(stdin))?

View file

@ -62,14 +62,14 @@ impl FromStr for ProcessSpawnOptionsStdioKind {
} }
} }
impl<'lua> FromLua<'lua> for ProcessSpawnOptionsStdioKind { impl FromLua for ProcessSpawnOptionsStdioKind {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
match value { match value {
LuaValue::Nil => Ok(Self::default()), LuaValue::Nil => Ok(Self::default()),
LuaValue::String(s) => s.to_str()?.parse(), LuaValue::String(s) => s.to_str()?.parse(),
_ => Err(LuaError::FromLuaConversionError { _ => Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "ProcessSpawnOptionsStdioKind", to: "ProcessSpawnOptionsStdioKind".to_string(),
message: Some(format!( message: Some(format!(
"Invalid spawn options stdio kind - expected string, got {}", "Invalid spawn options stdio kind - expected string, got {}",
value.type_name() value.type_name()

View file

@ -22,8 +22,8 @@ pub(super) struct ProcessSpawnOptions {
pub stdio: ProcessSpawnOptionsStdio, pub stdio: ProcessSpawnOptionsStdio,
} }
impl<'lua> FromLua<'lua> for ProcessSpawnOptions { impl FromLua for ProcessSpawnOptions {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
let mut this = Self::default(); let mut this = Self::default();
let value = match value { let value = match value {
LuaValue::Nil => return Ok(this), LuaValue::Nil => return Ok(this),
@ -31,7 +31,7 @@ impl<'lua> FromLua<'lua> for ProcessSpawnOptions {
_ => { _ => {
return Err(LuaError::FromLuaConversionError { return Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "ProcessSpawnOptions", to: "ProcessSpawnOptions".to_string(),
message: Some(format!( message: Some(format!(
"Invalid spawn options - expected table, got {}", "Invalid spawn options - expected table, got {}",
value.type_name() value.type_name()
@ -49,7 +49,7 @@ impl<'lua> FromLua<'lua> for ProcessSpawnOptions {
match value.get("cwd")? { match value.get("cwd")? {
LuaValue::Nil => {} LuaValue::Nil => {}
LuaValue::String(s) => { LuaValue::String(s) => {
let mut cwd = PathBuf::from(s.to_str()?); let mut cwd = PathBuf::from(s.to_str()?.to_string());
if let Ok(stripped) = cwd.strip_prefix("~") { if let Ok(stripped) = cwd.strip_prefix("~") {
let user_dirs = UserDirs::new().ok_or_else(|| { let user_dirs = UserDirs::new().ok_or_else(|| {
LuaError::runtime( LuaError::runtime(

View file

@ -19,8 +19,8 @@ impl From<ProcessSpawnOptionsStdioKind> for ProcessSpawnOptionsStdio {
} }
} }
impl<'lua> FromLua<'lua> for ProcessSpawnOptionsStdio { impl FromLua for ProcessSpawnOptionsStdio {
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
match value { match value {
LuaValue::Nil => Ok(Self::default()), LuaValue::Nil => Ok(Self::default()),
LuaValue::String(s) => { LuaValue::String(s) => {
@ -45,7 +45,7 @@ impl<'lua> FromLua<'lua> for ProcessSpawnOptionsStdio {
} }
_ => Err(LuaError::FromLuaConversionError { _ => Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "ProcessSpawnOptionsStdio", to: "ProcessSpawnOptionsStdio".to_string(),
message: Some(format!( message: Some(format!(
"Invalid spawn options stdio - expected string or table, got {}", "Invalid spawn options stdio - expected string or table, got {}",
value.type_name() value.type_name()

View file

@ -27,18 +27,21 @@ impl<R: AsyncRead + Unpin> ChildProcessReader<R> {
} }
impl<R: AsyncRead + Unpin + 'static> LuaUserData for ChildProcessReader<R> { impl<R: AsyncRead + Unpin + 'static> LuaUserData for ChildProcessReader<R> {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_async_method_mut("read", |lua, this, chunk_size: Option<usize>| async move { methods.add_async_method_mut(
let buf = this.read(chunk_size).await?; "read",
|lua, mut this, chunk_size: Option<usize>| async move {
let buf = this.read(chunk_size).await?;
if buf.is_empty() { if buf.is_empty() {
return Ok(LuaValue::Nil); return Ok(LuaValue::Nil);
} }
Ok(LuaValue::String(lua.create_string(buf)?)) Ok(LuaValue::String(lua.create_string(buf)?))
}); },
);
methods.add_async_method_mut("readToEnd", |lua, this, ()| async { methods.add_async_method_mut("readToEnd", |lua, mut this, ()| async move {
Ok(lua.create_string(this.read_to_end().await?)) Ok(lua.create_string(this.read_to_end().await?))
}); });
} }
@ -52,7 +55,9 @@ impl<W: AsyncWrite + Unpin> ChildProcessWriter<W> {
} }
impl<W: AsyncWrite + Unpin + 'static> LuaUserData for ChildProcessWriter<W> { impl<W: AsyncWrite + Unpin + 'static> LuaUserData for ChildProcessWriter<W> {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_async_method_mut("write", |_, this, data| async { this.write(data).await }); methods.add_async_method_mut("write", |_, mut this, data| async move {
this.write(data).await
});
} }
} }

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
regex = "1.10" regex = "1.10"
self_cell = "1.0" self_cell = "1.0"

View file

@ -58,7 +58,7 @@ impl LuaCaptures {
} }
impl LuaUserData for LuaCaptures { impl LuaUserData for LuaCaptures {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_method("get", |_, this, index: usize| { methods.add_method("get", |_, this, index: usize| {
Ok(this Ok(this
.captures() .captures()
@ -85,7 +85,7 @@ impl LuaUserData for LuaCaptures {
}); });
} }
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_meta_field(LuaMetaMethod::Type, "RegexCaptures"); fields.add_meta_field(LuaMetaMethod::Type, "RegexCaptures");
} }
} }

View file

@ -17,7 +17,7 @@ use self::regex::LuaRegex;
Errors when out of memory. Errors when out of memory.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("new", new_regex)? .with_function("new", new_regex)?
.build_readonly() .build_readonly()

View file

@ -34,7 +34,7 @@ impl LuaMatch {
} }
impl LuaUserData for LuaMatch { impl LuaUserData for LuaMatch {
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
// NOTE: Strings are 0 based in Rust but 1 based in Luau, and end of range in Rust is exclusive // NOTE: Strings are 0 based in Rust but 1 based in Luau, and end of range in Rust is exclusive
fields.add_field_method_get("start", |_, this| Ok(this.start.saturating_add(1))); fields.add_field_method_get("start", |_, this| Ok(this.start.saturating_add(1)));
fields.add_field_method_get("finish", |_, this| Ok(this.end)); fields.add_field_method_get("finish", |_, this| Ok(this.end));
@ -44,7 +44,7 @@ impl LuaUserData for LuaMatch {
fields.add_meta_field(LuaMetaMethod::Type, "RegexMatch"); fields.add_meta_field(LuaMetaMethod::Type, "RegexMatch");
} }
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(LuaMetaMethod::Len, |_, this, ()| Ok(this.range().len())); methods.add_meta_method(LuaMetaMethod::Len, |_, this, ()| Ok(this.range().len()));
methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| { methods.add_meta_method(LuaMetaMethod::ToString, |_, this, ()| {
Ok(this.slice().to_string()) Ok(this.slice().to_string())

View file

@ -25,7 +25,7 @@ impl LuaRegex {
} }
impl LuaUserData for LuaRegex { impl LuaUserData for LuaRegex {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_method("isMatch", |_, this, text: String| { methods.add_method("isMatch", |_, this, text: String| {
Ok(this.inner.is_match(&text)) Ok(this.inner.is_match(&text))
}); });
@ -70,7 +70,7 @@ impl LuaUserData for LuaRegex {
}); });
} }
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
fields.add_meta_field(LuaMetaMethod::Type, "Regex"); fields.add_meta_field(LuaMetaMethod::Type, "Regex");
} }
} }

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" } mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
rbx_cookie = { version = "0.1.4", default-features = false } rbx_cookie = { version = "0.1.4", default-features = false }

View file

@ -23,10 +23,10 @@ use roblox_install::RobloxStudio;
Errors when out of memory. Errors when out of memory.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
let mut roblox_constants = Vec::new(); let mut roblox_constants = Vec::new();
let roblox_module = lune_roblox::module(lua)?; let roblox_module = lune_roblox::module(lua.clone())?;
for pair in roblox_module.pairs::<LuaValue, LuaValue>() { for pair in roblox_module.pairs::<LuaValue, LuaValue>() {
roblox_constants.push(pair?); roblox_constants.push(pair?);
} }
@ -48,36 +48,30 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
.build_readonly() .build_readonly()
} }
async fn deserialize_place<'lua>( async fn deserialize_place(lua: Lua, contents: LuaString) -> LuaResult<LuaValue> {
lua: &'lua Lua,
contents: LuaString<'lua>,
) -> LuaResult<LuaValue<'lua>> {
let bytes = contents.as_bytes().to_vec(); let bytes = contents.as_bytes().to_vec();
let fut = lua.spawn_blocking(move || { let fut = lua.spawn_blocking(move || {
let doc = Document::from_bytes(bytes, DocumentKind::Place)?; let doc = Document::from_bytes(bytes, DocumentKind::Place)?;
let data_model = doc.into_data_model_instance()?; let data_model = doc.into_data_model_instance()?;
Ok::<_, DocumentError>(data_model) Ok::<_, DocumentError>(data_model)
}); });
fut.await.into_lua_err()?.into_lua(lua) fut.await.into_lua_err()?.into_lua(&lua)
} }
async fn deserialize_model<'lua>( async fn deserialize_model(lua: Lua, contents: LuaString) -> LuaResult<LuaValue> {
lua: &'lua Lua,
contents: LuaString<'lua>,
) -> LuaResult<LuaValue<'lua>> {
let bytes = contents.as_bytes().to_vec(); let bytes = contents.as_bytes().to_vec();
let fut = lua.spawn_blocking(move || { let fut = lua.spawn_blocking(move || {
let doc = Document::from_bytes(bytes, DocumentKind::Model)?; let doc = Document::from_bytes(bytes, DocumentKind::Model)?;
let instance_array = doc.into_instance_array()?; let instance_array = doc.into_instance_array()?;
Ok::<_, DocumentError>(instance_array) Ok::<_, DocumentError>(instance_array)
}); });
fut.await.into_lua_err()?.into_lua(lua) fut.await.into_lua_err()?.into_lua(&lua)
} }
async fn serialize_place<'lua>( async fn serialize_place(
lua: &'lua Lua, lua: Lua,
(data_model, as_xml): (LuaUserDataRef<'lua, Instance>, Option<bool>), (data_model, as_xml): (LuaUserDataRef<Instance>, Option<bool>),
) -> LuaResult<LuaString<'lua>> { ) -> LuaResult<LuaString> {
let data_model = *data_model; let data_model = *data_model;
let fut = lua.spawn_blocking(move || { let fut = lua.spawn_blocking(move || {
let doc = Document::from_data_model_instance(data_model)?; let doc = Document::from_data_model_instance(data_model)?;
@ -91,10 +85,10 @@ async fn serialize_place<'lua>(
lua.create_string(bytes) lua.create_string(bytes)
} }
async fn serialize_model<'lua>( async fn serialize_model(
lua: &'lua Lua, lua: Lua,
(instances, as_xml): (Vec<LuaUserDataRef<'lua, Instance>>, Option<bool>), (instances, as_xml): (Vec<LuaUserDataRef<Instance>>, Option<bool>),
) -> LuaResult<LuaString<'lua>> { ) -> LuaResult<LuaString> {
let instances = instances.iter().map(|i| **i).collect(); let instances = instances.iter().map(|i| **i).collect();
let fut = lua.spawn_blocking(move || { let fut = lua.spawn_blocking(move || {
let doc = Document::from_instance_array(instances)?; let doc = Document::from_instance_array(instances)?;

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau", "serialize"] } mlua = { version = "0.10.3", features = ["luau", "serialize"] }
async-compression = { version = "0.4", features = [ async-compression = { version = "0.4", features = [
"tokio", "tokio",

View file

@ -84,8 +84,8 @@ impl CompressDecompressFormat {
} }
} }
impl<'lua> FromLua<'lua> for CompressDecompressFormat { impl FromLua for CompressDecompressFormat {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::String(s) = &value { if let LuaValue::String(s) = &value {
match s.to_string_lossy().to_ascii_lowercase().trim() { match s.to_string_lossy().to_ascii_lowercase().trim() {
"brotli" => Ok(Self::Brotli), "brotli" => Ok(Self::Brotli),
@ -94,7 +94,7 @@ impl<'lua> FromLua<'lua> for CompressDecompressFormat {
"zlib" => Ok(Self::ZLib), "zlib" => Ok(Self::ZLib),
kind => Err(LuaError::FromLuaConversionError { kind => Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "CompressDecompressFormat", to: "CompressDecompressFormat".to_string(),
message: Some(format!( message: Some(format!(
"Invalid format '{kind}', valid formats are: brotli, gzip, lz4, zlib" "Invalid format '{kind}', valid formats are: brotli, gzip, lz4, zlib"
)), )),
@ -103,7 +103,7 @@ impl<'lua> FromLua<'lua> for CompressDecompressFormat {
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "CompressDecompressFormat", to: "CompressDecompressFormat".to_string(),
message: None, message: None,
}) })
} }

View file

@ -28,8 +28,8 @@ pub enum EncodeDecodeFormat {
Toml, Toml,
} }
impl<'lua> FromLua<'lua> for EncodeDecodeFormat { impl FromLua for EncodeDecodeFormat {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::String(s) = &value { if let LuaValue::String(s) = &value {
match s.to_string_lossy().to_ascii_lowercase().trim() { match s.to_string_lossy().to_ascii_lowercase().trim() {
"json" => Ok(Self::Json), "json" => Ok(Self::Json),
@ -37,7 +37,7 @@ impl<'lua> FromLua<'lua> for EncodeDecodeFormat {
"toml" => Ok(Self::Toml), "toml" => Ok(Self::Toml),
kind => Err(LuaError::FromLuaConversionError { kind => Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "EncodeDecodeFormat", to: "EncodeDecodeFormat".to_string(),
message: Some(format!( message: Some(format!(
"Invalid format '{kind}', valid formats are: json, yaml, toml" "Invalid format '{kind}', valid formats are: json, yaml, toml"
)), )),
@ -46,7 +46,7 @@ impl<'lua> FromLua<'lua> for EncodeDecodeFormat {
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "EncodeDecodeFormat", to: "EncodeDecodeFormat".to_string(),
message: None, message: None,
}) })
} }
@ -89,11 +89,7 @@ impl From<(EncodeDecodeFormat, bool)> for EncodeDecodeConfig {
Errors when the encoding fails. Errors when the encoding fails.
*/ */
pub fn encode<'lua>( pub fn encode(value: LuaValue, lua: &Lua, config: EncodeDecodeConfig) -> LuaResult<LuaString> {
value: LuaValue<'lua>,
lua: &'lua Lua,
config: EncodeDecodeConfig,
) -> LuaResult<LuaString<'lua>> {
let bytes = match config.format { let bytes = match config.format {
EncodeDecodeFormat::Json => { EncodeDecodeFormat::Json => {
let serialized: JsonValue = lua.from_value_with(value, LUA_DESERIALIZE_OPTIONS)?; let serialized: JsonValue = lua.from_value_with(value, LUA_DESERIALIZE_OPTIONS)?;

View file

@ -120,7 +120,7 @@ impl HashOptions {
.secret .secret
.ok_or_else(|| LuaError::FromLuaConversionError { .ok_or_else(|| LuaError::FromLuaConversionError {
from: "nil", from: "nil",
to: "string or buffer", to: "string or buffer".to_string(),
message: Some("Argument #3 missing or nil".to_string()), message: Some("Argument #3 missing or nil".to_string()),
})?; })?;
@ -174,8 +174,8 @@ impl HashOptions {
} }
} }
impl<'lua> FromLua<'lua> for HashAlgorithm { impl FromLua for HashAlgorithm {
fn from_lua(value: LuaValue<'lua>, _lua: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _lua: &Lua) -> LuaResult<Self> {
if let LuaValue::String(str) = value { if let LuaValue::String(str) = value {
/* /*
Casing tends to vary for algorithms, so rather than force Casing tends to vary for algorithms, so rather than force
@ -200,7 +200,7 @@ impl<'lua> FromLua<'lua> for HashAlgorithm {
_ => Err(LuaError::FromLuaConversionError { _ => Err(LuaError::FromLuaConversionError {
from: "string", from: "string",
to: "HashAlgorithm", to: "HashAlgorithm".to_string(),
message: Some(format!( message: Some(format!(
"Invalid hashing algorithm '{str}', valid kinds are:\n{}", "Invalid hashing algorithm '{str}', valid kinds are:\n{}",
HashAlgorithm::ALL HashAlgorithm::ALL
@ -214,22 +214,22 @@ impl<'lua> FromLua<'lua> for HashAlgorithm {
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "HashAlgorithm", to: "HashAlgorithm".to_string(),
message: None, message: None,
}) })
} }
} }
} }
impl<'lua> FromLuaMulti<'lua> for HashOptions { impl FromLuaMulti for HashOptions {
fn from_lua_multi(mut values: LuaMultiValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> { fn from_lua_multi(mut values: LuaMultiValue, lua: &Lua) -> LuaResult<Self> {
let algorithm = values let algorithm = values
.pop_front() .pop_front()
.map(|value| HashAlgorithm::from_lua(value, lua)) .map(|value| HashAlgorithm::from_lua(value, lua))
.transpose()? .transpose()?
.ok_or_else(|| LuaError::FromLuaConversionError { .ok_or_else(|| LuaError::FromLuaConversionError {
from: "nil", from: "nil",
to: "HashAlgorithm", to: "HashOptions".to_string(),
message: Some("Argument #1 missing or nil".to_string()), message: Some("Argument #1 missing or nil".to_string()),
})?; })?;
let message = values let message = values
@ -238,7 +238,7 @@ impl<'lua> FromLuaMulti<'lua> for HashOptions {
.transpose()? .transpose()?
.ok_or_else(|| LuaError::FromLuaConversionError { .ok_or_else(|| LuaError::FromLuaConversionError {
from: "nil", from: "nil",
to: "string or buffer", to: "string or buffer".to_string(),
message: Some("Argument #2 missing or nil".to_string()), message: Some("Argument #2 missing or nil".to_string()),
})?; })?;
let secret = values let secret = values

View file

@ -20,7 +20,7 @@ pub use self::hash::HashOptions;
Errors when out of memory. Errors when out of memory.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("encode", serde_encode)? .with_function("encode", serde_encode)?
.with_function("decode", serde_decode)? .with_function("decode", serde_decode)?
@ -31,10 +31,10 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
.build_readonly() .build_readonly()
} }
fn serde_encode<'lua>( fn serde_encode(
lua: &'lua Lua, lua: &Lua,
(format, value, pretty): (EncodeDecodeFormat, LuaValue<'lua>, Option<bool>), (format, value, pretty): (EncodeDecodeFormat, LuaValue, Option<bool>),
) -> LuaResult<LuaString<'lua>> { ) -> LuaResult<LuaString> {
let config = EncodeDecodeConfig::from((format, pretty.unwrap_or_default())); let config = EncodeDecodeConfig::from((format, pretty.unwrap_or_default()));
encode(value, lua, config) encode(value, lua, config)
} }
@ -45,7 +45,7 @@ fn serde_decode(lua: &Lua, (format, bs): (EncodeDecodeFormat, BString)) -> LuaRe
} }
async fn serde_compress( async fn serde_compress(
lua: &Lua, lua: Lua,
(format, bs, level): (CompressDecompressFormat, BString, Option<i32>), (format, bs, level): (CompressDecompressFormat, BString, Option<i32>),
) -> LuaResult<LuaString> { ) -> LuaResult<LuaString> {
let bytes = compress(bs, format, level).await?; let bytes = compress(bs, format, level).await?;
@ -53,7 +53,7 @@ async fn serde_compress(
} }
async fn serde_decompress( async fn serde_decompress(
lua: &Lua, lua: Lua,
(format, bs): (CompressDecompressFormat, BString), (format, bs): (CompressDecompressFormat, BString),
) -> LuaResult<LuaString> { ) -> LuaResult<LuaString> {
let bytes = decompress(bs, format).await?; let bytes = decompress(bs, format).await?;

View file

@ -14,7 +14,7 @@ workspace = true
[dependencies] [dependencies]
dialoguer = "0.11" dialoguer = "0.11"
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau", "error-send"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" } mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
tokio = { version = "1", default-features = false, features = [ tokio = { version = "1", default-features = false, features = [

View file

@ -25,7 +25,7 @@ const FORMAT_CONFIG: ValueFormatConfig = ValueFormatConfig::new()
Errors when out of memory. Errors when out of memory.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("color", stdio_color)? .with_function("color", stdio_color)?
.with_function("style", stdio_style)? .with_function("style", stdio_style)?
@ -49,16 +49,16 @@ fn stdio_format(_: &Lua, args: LuaMultiValue) -> LuaResult<String> {
Ok(pretty_format_multi_value(&args, &FORMAT_CONFIG)) Ok(pretty_format_multi_value(&args, &FORMAT_CONFIG))
} }
async fn stdio_write(_: &Lua, s: LuaString<'_>) -> LuaResult<()> { async fn stdio_write(_: Lua, s: LuaString) -> LuaResult<()> {
let mut stdout = stdout(); let mut stdout = stdout();
stdout.write_all(s.as_bytes()).await?; stdout.write_all(&s.as_bytes()).await?;
stdout.flush().await?; stdout.flush().await?;
Ok(()) Ok(())
} }
async fn stdio_ewrite(_: &Lua, s: LuaString<'_>) -> LuaResult<()> { async fn stdio_ewrite(_: Lua, s: LuaString) -> LuaResult<()> {
let mut stderr = stderr(); let mut stderr = stderr();
stderr.write_all(s.as_bytes()).await?; stderr.write_all(&s.as_bytes()).await?;
stderr.flush().await?; stderr.flush().await?;
Ok(()) Ok(())
} }
@ -71,14 +71,14 @@ async fn stdio_ewrite(_: &Lua, s: LuaString<'_>) -> LuaResult<()> {
having that capture the first two lines and then read the rest of the input. having that capture the first two lines and then read the rest of the input.
*/ */
async fn stdio_read_to_end(lua: &Lua, (): ()) -> LuaResult<LuaString> { async fn stdio_read_to_end(lua: Lua, (): ()) -> LuaResult<LuaString> {
let mut input = Vec::new(); let mut input = Vec::new();
let mut stdin = stdin(); let mut stdin = stdin();
stdin.read_to_end(&mut input).await?; stdin.read_to_end(&mut input).await?;
lua.create_string(&input) lua.create_string(&input)
} }
async fn stdio_prompt(lua: &Lua, options: PromptOptions) -> LuaResult<PromptResult> { async fn stdio_prompt(lua: Lua, options: PromptOptions) -> LuaResult<PromptResult> {
lua.spawn_blocking(move || prompt(options)) lua.spawn_blocking(move || prompt(options))
.await .await
.into_lua_err() .into_lua_err()

View file

@ -49,15 +49,15 @@ impl fmt::Display for PromptKind {
} }
} }
impl<'lua> FromLua<'lua> for PromptKind { impl FromLua for PromptKind {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::Nil = value { if let LuaValue::Nil = value {
Ok(Self::default()) Ok(Self::default())
} else if let LuaValue::String(s) = value { } else if let LuaValue::String(s) = value {
let s = s.to_str()?; let s = s.to_str()?;
s.parse().map_err(|()| LuaError::FromLuaConversionError { s.parse().map_err(|()| LuaError::FromLuaConversionError {
from: "string", from: "string",
to: "PromptKind", to: "PromptKind".to_string(),
message: Some(format!( message: Some(format!(
"Invalid prompt kind '{s}', valid kinds are:\n{}", "Invalid prompt kind '{s}', valid kinds are:\n{}",
PromptKind::ALL PromptKind::ALL
@ -70,7 +70,7 @@ impl<'lua> FromLua<'lua> for PromptKind {
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: "nil", from: "nil",
to: "PromptKind", to: "PromptKind".to_string(),
message: None, message: None,
}) })
} }
@ -85,8 +85,8 @@ pub struct PromptOptions {
pub options: Option<Vec<String>>, pub options: Option<Vec<String>>,
} }
impl<'lua> FromLuaMulti<'lua> for PromptOptions { impl FromLuaMulti for PromptOptions {
fn from_lua_multi(mut values: LuaMultiValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> { fn from_lua_multi(mut values: LuaMultiValue, lua: &Lua) -> LuaResult<Self> {
// Argument #1 - prompt kind (optional) // Argument #1 - prompt kind (optional)
let kind = values let kind = values
.pop_front() .pop_front()
@ -118,7 +118,7 @@ impl<'lua> FromLuaMulti<'lua> for PromptOptions {
value => { value => {
return Err(LuaError::FromLuaConversionError { return Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "PromptOptions", to: "PromptOptions".to_string(),
message: Some("Argument #3 must be a boolean, table, or nil".to_string()), message: Some("Argument #3 must be a boolean, table, or nil".to_string()),
}) })
} }
@ -133,14 +133,14 @@ impl<'lua> FromLuaMulti<'lua> for PromptOptions {
if matches!(kind, PromptKind::Confirm) && text.is_none() { if matches!(kind, PromptKind::Confirm) && text.is_none() {
return Err(LuaError::FromLuaConversionError { return Err(LuaError::FromLuaConversionError {
from: "nil", from: "nil",
to: "PromptOptions", to: "PromptOptions".to_string(),
message: Some("Argument #2 missing or nil".to_string()), message: Some("Argument #2 missing or nil".to_string()),
}); });
} }
if matches!(kind, PromptKind::Select | PromptKind::MultiSelect) && options.is_none() { if matches!(kind, PromptKind::Select | PromptKind::MultiSelect) && options.is_none() {
return Err(LuaError::FromLuaConversionError { return Err(LuaError::FromLuaConversionError {
from: "nil", from: "nil",
to: "PromptOptions", to: "PromptOptions".to_string(),
message: Some("Argument #3 missing or nil".to_string()), message: Some("Argument #3 missing or nil".to_string()),
}); });
} }
@ -164,8 +164,8 @@ pub enum PromptResult {
None, None,
} }
impl<'lua> IntoLua<'lua> for PromptResult { impl IntoLua for PromptResult {
fn into_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
Ok(match self { Ok(match self {
Self::String(s) => LuaValue::String(lua.create_string(&s)?), Self::String(s) => LuaValue::String(lua.create_string(&s)?),
Self::Boolean(b) => LuaValue::Boolean(b), Self::Boolean(b) => LuaValue::Boolean(b),

View file

@ -88,7 +88,7 @@ impl FromStr for ColorKind {
} }
} }
impl FromLua<'_> for ColorKind { impl FromLua for ColorKind {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::String(s) = value { if let LuaValue::String(s) = value {
let s = s.to_str()?; let s = s.to_str()?;
@ -96,7 +96,7 @@ impl FromLua<'_> for ColorKind {
Ok(color) => Ok(color), Ok(color) => Ok(color),
Err(()) => Err(LuaError::FromLuaConversionError { Err(()) => Err(LuaError::FromLuaConversionError {
from: "string", from: "string",
to: "ColorKind", to: "ColorKind".to_string(),
message: Some(format!( message: Some(format!(
"Invalid color kind '{s}'\nValid kinds are: {}", "Invalid color kind '{s}'\nValid kinds are: {}",
Self::ALL Self::ALL
@ -110,7 +110,7 @@ impl FromLua<'_> for ColorKind {
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "ColorKind", to: "ColorKind".to_string(),
message: None, message: None,
}) })
} }
@ -165,7 +165,7 @@ impl FromStr for StyleKind {
} }
} }
impl FromLua<'_> for StyleKind { impl FromLua for StyleKind {
fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
if let LuaValue::String(s) = value { if let LuaValue::String(s) = value {
let s = s.to_str()?; let s = s.to_str()?;
@ -173,7 +173,7 @@ impl FromLua<'_> for StyleKind {
Ok(style) => Ok(style), Ok(style) => Ok(style),
Err(()) => Err(LuaError::FromLuaConversionError { Err(()) => Err(LuaError::FromLuaConversionError {
from: "string", from: "string",
to: "StyleKind", to: "StyleKind".to_string(),
message: Some(format!( message: Some(format!(
"Invalid style kind '{s}'\nValid kinds are: {}", "Invalid style kind '{s}'\nValid kinds are: {}",
Self::ALL Self::ALL
@ -187,7 +187,7 @@ impl FromLua<'_> for StyleKind {
} else { } else {
Err(LuaError::FromLuaConversionError { Err(LuaError::FromLuaConversionError {
from: value.type_name(), from: value.type_name(),
to: "StyleKind", to: "StyleKind".to_string(),
message: None, message: None,
}) })
} }

View file

@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true workspace = true
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" } mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
tokio = { version = "1", default-features = false, features = ["time"] } tokio = { version = "1", default-features = false, features = ["time"] }

View file

@ -16,13 +16,13 @@ use lune_utils::TableBuilder;
Errors when out of memory, or if default Lua globals are missing. Errors when out of memory, or if default Lua globals are missing.
*/ */
pub fn module(lua: &Lua) -> LuaResult<LuaTable> { pub fn module(lua: Lua) -> LuaResult<LuaTable> {
let fns = Functions::new(lua)?; let fns = Functions::new(lua.clone())?;
// Create wait & delay functions // Create wait & delay functions
let task_wait = lua.create_async_function(wait)?; let task_wait = lua.create_async_function(wait)?;
let task_delay_env = TableBuilder::new(lua)? let task_delay_env = TableBuilder::new(lua.clone())?
.with_value("select", lua.globals().get::<_, LuaFunction>("select")?)? .with_value("select", lua.globals().get::<LuaFunction>("select")?)?
.with_value("spawn", fns.spawn.clone())? .with_value("spawn", fns.spawn.clone())?
.with_value("defer", fns.defer.clone())? .with_value("defer", fns.defer.clone())?
.with_value("wait", task_wait.clone())? .with_value("wait", task_wait.clone())?
@ -49,7 +49,7 @@ return defer(function(...)
end, ...) end, ...)
"; ";
async fn wait(_: &Lua, secs: Option<f64>) -> LuaResult<f64> { async fn wait(_: Lua, secs: Option<f64>) -> LuaResult<f64> {
let duration = Duration::from_secs_f64(secs.unwrap_or_default()); let duration = Duration::from_secs_f64(secs.unwrap_or_default());
let before = Instant::now(); let before = Instant::now();

View file

@ -38,7 +38,7 @@ stdio = ["dep:lune-std-stdio"]
task = ["dep:lune-std-task"] task = ["dep:lune-std-task"]
[dependencies] [dependencies]
mlua = { version = "0.9.9", features = ["luau"] } mlua = { version = "0.10.3", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" } mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }

View file

@ -49,7 +49,7 @@ impl LuneStandardGlobal {
*/ */
#[rustfmt::skip] #[rustfmt::skip]
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
pub fn create<'lua>(&self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> { pub fn create(&self, lua: Lua) -> LuaResult<LuaValue> {
let res = match self { let res = match self {
Self::GTable => crate::globals::g_table::create(lua), Self::GTable => crate::globals::g_table::create(lua),
Self::Print => crate::globals::print::create(lua), Self::Print => crate::globals::print::create(lua),

View file

@ -1,5 +1,5 @@
use mlua::prelude::*; use mlua::prelude::*;
pub fn create(lua: &Lua) -> LuaResult<LuaValue> { pub fn create(lua: Lua) -> LuaResult<LuaValue> {
lua.create_table()?.into_lua(lua) lua.create_table()?.into_lua(&lua)
} }

View file

@ -7,13 +7,13 @@ const FORMAT_CONFIG: ValueFormatConfig = ValueFormatConfig::new()
.with_max_depth(4) .with_max_depth(4)
.with_colors_enabled(true); .with_colors_enabled(true);
pub fn create(lua: &Lua) -> LuaResult<LuaValue> { pub fn create(lua: Lua) -> LuaResult<LuaValue> {
let f = lua.create_function(|_, args: LuaMultiValue| { let f = lua.create_function(|_: &Lua, args: LuaMultiValue| {
let formatted = format!("{}\n", pretty_format_multi_value(&args, &FORMAT_CONFIG)); let formatted = format!("{}\n", pretty_format_multi_value(&args, &FORMAT_CONFIG));
let mut stdout = std::io::stdout(); let mut stdout = std::io::stdout();
stdout.write_all(formatted.as_bytes())?; stdout.write_all(formatted.as_bytes())?;
stdout.flush()?; stdout.flush()?;
Ok(()) Ok(())
})?; })?;
f.into_lua(lua) f.into_lua(&lua)
} }

View file

@ -6,16 +6,13 @@ use crate::luaurc::LuauRc;
use super::context::*; use super::context::*;
pub(super) async fn require<'lua, 'ctx>( pub(super) async fn require(
lua: &'lua Lua, lua: Lua,
ctx: &'ctx RequireContext, ctx: &RequireContext,
source: &str, source: &str,
alias: &str, alias: &str,
path: &str, path: &str,
) -> LuaResult<LuaMultiValue<'lua>> ) -> LuaResult<LuaMultiValue> {
where
'lua: 'ctx,
{
let alias = alias.to_ascii_lowercase(); let alias = alias.to_ascii_lowercase();
let parent = clean_path_and_make_absolute(source) let parent = clean_path_and_make_absolute(source)

View file

@ -100,11 +100,7 @@ impl RequireContext {
Will panic if the path has not been cached, use [`is_cached`] first. Will panic if the path has not been cached, use [`is_cached`] first.
*/ */
pub fn get_from_cache<'lua>( pub fn get_from_cache(&self, lua: Lua, abs_path: impl AsRef<Path>) -> LuaResult<LuaMultiValue> {
&self,
lua: &'lua Lua,
abs_path: impl AsRef<Path>,
) -> LuaResult<LuaMultiValue<'lua>> {
let results = self let results = self
.results .results
.try_lock() .try_lock()
@ -129,11 +125,11 @@ impl RequireContext {
Will panic if the path has not been cached, use [`is_cached`] first. Will panic if the path has not been cached, use [`is_cached`] first.
*/ */
pub async fn wait_for_cache<'lua>( pub async fn wait_for_cache(
&self, &self,
lua: &'lua Lua, lua: Lua,
abs_path: impl AsRef<Path>, abs_path: impl AsRef<Path>,
) -> LuaResult<LuaMultiValue<'lua>> { ) -> LuaResult<LuaMultiValue> {
let mut thread_recv = { let mut thread_recv = {
let pending = self let pending = self
.pending .pending
@ -152,7 +148,7 @@ impl RequireContext {
async fn load( async fn load(
&self, &self,
lua: &Lua, lua: Lua,
abs_path: impl AsRef<Path>, abs_path: impl AsRef<Path>,
rel_path: impl AsRef<Path>, rel_path: impl AsRef<Path>,
) -> LuaResult<LuaRegistryKey> { ) -> LuaResult<LuaRegistryKey> {
@ -188,12 +184,12 @@ impl RequireContext {
/** /**
Loads (requires) the file at the given path. Loads (requires) the file at the given path.
*/ */
pub async fn load_with_caching<'lua>( pub async fn load_with_caching(
&self, &self,
lua: &'lua Lua, lua: Lua,
abs_path: impl AsRef<Path>, abs_path: impl AsRef<Path>,
rel_path: impl AsRef<Path>, rel_path: impl AsRef<Path>,
) -> LuaResult<LuaMultiValue<'lua>> { ) -> LuaResult<LuaMultiValue> {
let abs_path = abs_path.as_ref(); let abs_path = abs_path.as_ref();
let rel_path = rel_path.as_ref(); let rel_path = rel_path.as_ref();
@ -205,7 +201,7 @@ impl RequireContext {
.insert(abs_path.to_path_buf(), broadcast_tx); .insert(abs_path.to_path_buf(), broadcast_tx);
// Try to load at this abs path // Try to load at this abs path
let load_res = self.load(lua, abs_path, rel_path).await; let load_res = self.load(lua.clone(), abs_path, rel_path).await;
let load_val = match &load_res { let load_val = match &load_res {
Err(e) => Err(e.clone()), Err(e) => Err(e.clone()),
Ok(k) => { Ok(k) => {
@ -241,11 +237,7 @@ impl RequireContext {
/** /**
Loads (requires) the library with the given name. Loads (requires) the library with the given name.
*/ */
pub fn load_library<'lua>( pub fn load_library(&self, lua: Lua, name: impl AsRef<str>) -> LuaResult<LuaMultiValue> {
&self,
lua: &'lua Lua,
name: impl AsRef<str>,
) -> LuaResult<LuaMultiValue<'lua>> {
let library: LuneStandardLibrary = match name.as_ref().parse() { let library: LuneStandardLibrary = match name.as_ref().parse() {
Err(e) => return Err(LuaError::runtime(e)), Err(e) => return Err(LuaError::runtime(e)),
Ok(b) => b, Ok(b) => b,
@ -268,7 +260,7 @@ impl RequireContext {
}; };
} }
let result = library.module(lua); let result = library.module(lua.clone());
cache.insert( cache.insert(
library, library,

View file

@ -2,13 +2,6 @@ use mlua::prelude::*;
use super::context::*; use super::context::*;
pub(super) fn require<'lua, 'ctx>( pub(super) fn require(lua: Lua, ctx: &RequireContext, name: &str) -> LuaResult<LuaMultiValue> {
lua: &'lua Lua,
ctx: &'ctx RequireContext,
name: &str,
) -> LuaResult<LuaMultiValue<'lua>>
where
'lua: 'ctx,
{
ctx.load_library(lua, name) ctx.load_library(lua, name)
} }

View file

@ -13,7 +13,7 @@ const REQUIRE_IMPL: &str = r"
return require(source(), ...) return require(source(), ...)
"; ";
pub fn create(lua: &Lua) -> LuaResult<LuaValue> { pub fn create(lua: Lua) -> LuaResult<LuaValue> {
lua.set_app_data(RequireContext::new()); lua.set_app_data(RequireContext::new());
/* /*
@ -48,7 +48,7 @@ pub fn create(lua: &Lua) -> LuaResult<LuaValue> {
}, },
})?; })?;
let require_env = TableBuilder::new(lua)? let require_env = TableBuilder::new(lua.clone())?
.with_value("source", get_source_fn)? .with_value("source", get_source_fn)?
.with_value("require", require_fn)? .with_value("require", require_fn)?
.build_readonly()?; .build_readonly()?;
@ -57,13 +57,10 @@ pub fn create(lua: &Lua) -> LuaResult<LuaValue> {
.set_name("require") .set_name("require")
.set_environment(require_env) .set_environment(require_env)
.into_function()? .into_function()?
.into_lua(lua) .into_lua(&lua)
} }
async fn require<'lua>( async fn require(lua: Lua, (source, path): (LuaString, LuaString)) -> LuaResult<LuaMultiValue> {
lua: &'lua Lua,
(source, path): (LuaString<'lua>, LuaString<'lua>),
) -> LuaResult<LuaMultiValue<'lua>> {
let source = source let source = source
.to_str() .to_str()
.into_lua_err() .into_lua_err()
@ -77,8 +74,9 @@ async fn require<'lua>(
.to_string(); .to_string();
let context = lua let context = lua
.app_data_ref() .app_data_ref::<RequireContext>()
.expect("Failed to get RequireContext from app data"); .expect("Failed to get RequireContext from app data")
.clone();
if let Some(builtin_name) = path.strip_prefix("@lune/").map(str::to_ascii_lowercase) { if let Some(builtin_name) = path.strip_prefix("@lune/").map(str::to_ascii_lowercase) {
library::require(lua, &context, &builtin_name) library::require(lua, &context, &builtin_name)

View file

@ -5,30 +5,24 @@ use mlua::Error::ExternalError;
use super::context::*; use super::context::*;
pub(super) async fn require<'lua, 'ctx>( pub(super) async fn require(
lua: &'lua Lua, lua: Lua,
ctx: &'ctx RequireContext, ctx: &RequireContext,
source: &str, source: &str,
path: &str, path: &str,
) -> LuaResult<LuaMultiValue<'lua>> ) -> LuaResult<LuaMultiValue> {
where
'lua: 'ctx,
{
let (abs_path, rel_path) = RequireContext::resolve_paths(source, path)?; let (abs_path, rel_path) = RequireContext::resolve_paths(source, path)?;
require_abs_rel(lua, ctx, abs_path, rel_path).await require_abs_rel(lua, ctx, abs_path, rel_path).await
} }
pub(super) async fn require_abs_rel<'lua, 'ctx>( pub(super) async fn require_abs_rel(
lua: &'lua Lua, lua: Lua,
ctx: &'ctx RequireContext, ctx: &RequireContext,
abs_path: PathBuf, // Absolute to filesystem abs_path: PathBuf, // Absolute to filesystem
rel_path: PathBuf, // Relative to CWD (for displaying) rel_path: PathBuf, // Relative to CWD (for displaying)
) -> LuaResult<LuaMultiValue<'lua>> ) -> LuaResult<LuaMultiValue> {
where
'lua: 'ctx,
{
// 1. Try to require the exact path // 1. Try to require the exact path
match require_inner(lua, ctx, &abs_path, &rel_path).await { match require_inner(lua.clone(), ctx, &abs_path, &rel_path).await {
Ok(res) => return Ok(res), Ok(res) => return Ok(res),
Err(err) => { Err(err) => {
if !is_file_not_found_error(&err) { if !is_file_not_found_error(&err) {
@ -41,7 +35,7 @@ where
// 3. Try to require the path with an added "lua" extension // 3. Try to require the path with an added "lua" extension
for extension in ["luau", "lua"] { for extension in ["luau", "lua"] {
match require_inner( match require_inner(
lua, lua.clone(),
ctx, ctx,
&append_extension(&abs_path, extension), &append_extension(&abs_path, extension),
&append_extension(&rel_path, extension), &append_extension(&rel_path, extension),
@ -66,7 +60,7 @@ where
// 5. Try to require the init path with an added "lua" extension // 5. Try to require the init path with an added "lua" extension
for extension in ["luau", "lua"] { for extension in ["luau", "lua"] {
match require_inner( match require_inner(
lua, lua.clone(),
ctx, ctx,
&append_extension(&abs_init, extension), &append_extension(&abs_init, extension),
&append_extension(&rel_init, extension), &append_extension(&rel_init, extension),
@ -89,15 +83,12 @@ where
))) )))
} }
async fn require_inner<'lua, 'ctx>( async fn require_inner(
lua: &'lua Lua, lua: Lua,
ctx: &'ctx RequireContext, ctx: &RequireContext,
abs_path: impl AsRef<Path>, abs_path: impl AsRef<Path>,
rel_path: impl AsRef<Path>, rel_path: impl AsRef<Path>,
) -> LuaResult<LuaMultiValue<'lua>> ) -> LuaResult<LuaMultiValue> {
where
'lua: 'ctx,
{
let abs_path = abs_path.as_ref(); let abs_path = abs_path.as_ref();
let rel_path = rel_path.as_ref(); let rel_path = rel_path.as_ref();

View file

@ -6,13 +6,13 @@ struct Version(String);
impl LuaUserData for Version {} impl LuaUserData for Version {}
pub fn create(lua: &Lua) -> LuaResult<LuaValue> { pub fn create(lua: Lua) -> LuaResult<LuaValue> {
let v = match lua.app_data_ref::<Version>() { let v = match lua.app_data_ref::<Version>() {
Some(v) => v.0.to_string(), Some(v) => v.0.to_string(),
None => env!("CARGO_PKG_VERSION").to_string(), None => env!("CARGO_PKG_VERSION").to_string(),
}; };
let s = get_version_string(v); let s = get_version_string(v);
lua.create_string(s)?.into_lua(lua) lua.create_string(s)?.into_lua(&lua)
} }
/** /**

View file

@ -7,8 +7,8 @@ const FORMAT_CONFIG: ValueFormatConfig = ValueFormatConfig::new()
.with_max_depth(4) .with_max_depth(4)
.with_colors_enabled(true); .with_colors_enabled(true);
pub fn create(lua: &Lua) -> LuaResult<LuaValue> { pub fn create(lua: Lua) -> LuaResult<LuaValue> {
let f = lua.create_function(|_, args: LuaMultiValue| { let f = lua.create_function(|_: &Lua, args: LuaMultiValue| {
let formatted = format!( let formatted = format!(
"{}\n{}\n", "{}\n{}\n",
Label::Warn, Label::Warn,
@ -19,5 +19,5 @@ pub fn create(lua: &Lua) -> LuaResult<LuaValue> {
stdout.flush()?; stdout.flush()?;
Ok(()) Ok(())
})?; })?;
f.into_lua(lua) f.into_lua(&lua)
} }

Some files were not shown because too many files have changed in this diff Show more