mirror of
https://github.com/lune-org/lune.git
synced 2024-12-13 13:30:38 +00:00
Use plain tables instead of userdata for globals
This commit is contained in:
parent
d5b3d3f94b
commit
e6faa3f6be
7 changed files with 105 additions and 170 deletions
|
@ -1,35 +1,22 @@
|
||||||
use mlua::{Lua, MultiValue, Result, UserData, UserDataMethods};
|
use mlua::{Lua, MultiValue, Result, Table};
|
||||||
|
|
||||||
use crate::utils::formatting::{
|
use crate::utils::formatting::{
|
||||||
flush_stdout, pretty_format_multi_value, print_color, print_label, print_style,
|
flush_stdout, pretty_format_multi_value, print_color, print_label, print_style,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Console();
|
pub fn new(lua: &Lua) -> Result<Table> {
|
||||||
|
let tab = lua.create_table()?;
|
||||||
impl Console {
|
tab.raw_set("resetColor", lua.create_function(console_reset_color)?)?;
|
||||||
pub fn new() -> Self {
|
tab.raw_set("setColor", lua.create_function(console_set_color)?)?;
|
||||||
Self()
|
tab.raw_set("resetStyle", lua.create_function(console_reset_style)?)?;
|
||||||
}
|
tab.raw_set("setStyle", lua.create_function(console_set_style)?)?;
|
||||||
}
|
tab.raw_set("format", lua.create_function(console_format)?)?;
|
||||||
|
tab.raw_set("log", lua.create_function(console_log)?)?;
|
||||||
impl Default for Console {
|
tab.raw_set("info", lua.create_function(console_info)?)?;
|
||||||
fn default() -> Self {
|
tab.raw_set("warn", lua.create_function(console_warn)?)?;
|
||||||
Self::new()
|
tab.raw_set("error", lua.create_function(console_error)?)?;
|
||||||
}
|
tab.set_readonly(true);
|
||||||
}
|
Ok(tab)
|
||||||
|
|
||||||
impl UserData for Console {
|
|
||||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
|
||||||
methods.add_function("resetColor", console_reset_color);
|
|
||||||
methods.add_function("setColor", console_set_color);
|
|
||||||
methods.add_function("resetStyle", console_reset_style);
|
|
||||||
methods.add_function("setStyle", console_set_style);
|
|
||||||
methods.add_function("format", console_format);
|
|
||||||
methods.add_function("log", console_log);
|
|
||||||
methods.add_function("info", console_info);
|
|
||||||
methods.add_function("warn", console_warn);
|
|
||||||
methods.add_function("error", console_error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn console_reset_color(_: &Lua, _: ()) -> Result<()> {
|
fn console_reset_color(_: &Lua, _: ()) -> Result<()> {
|
||||||
|
|
|
@ -1,33 +1,20 @@
|
||||||
use std::path::{PathBuf, MAIN_SEPARATOR};
|
use std::path::{PathBuf, MAIN_SEPARATOR};
|
||||||
|
|
||||||
use mlua::{Lua, Result, UserData, UserDataMethods};
|
use mlua::{Lua, Result, Table};
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
pub struct Fs();
|
pub fn new(lua: &Lua) -> Result<Table> {
|
||||||
|
let tab = lua.create_table()?;
|
||||||
impl Fs {
|
tab.raw_set("readFile", lua.create_async_function(fs_read_file)?)?;
|
||||||
pub fn new() -> Self {
|
tab.raw_set("readDir", lua.create_async_function(fs_read_dir)?)?;
|
||||||
Self()
|
tab.raw_set("writeFile", lua.create_async_function(fs_write_file)?)?;
|
||||||
}
|
tab.raw_set("writeDir", lua.create_async_function(fs_write_dir)?)?;
|
||||||
}
|
tab.raw_set("removeFile", lua.create_async_function(fs_remove_file)?)?;
|
||||||
|
tab.raw_set("removeDir", lua.create_async_function(fs_remove_dir)?)?;
|
||||||
impl Default for Fs {
|
tab.raw_set("isFile", lua.create_async_function(fs_is_file)?)?;
|
||||||
fn default() -> Self {
|
tab.raw_set("isDir", lua.create_async_function(fs_is_dir)?)?;
|
||||||
Self::new()
|
tab.set_readonly(true);
|
||||||
}
|
Ok(tab)
|
||||||
}
|
|
||||||
|
|
||||||
impl UserData for Fs {
|
|
||||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
|
||||||
methods.add_async_function("readFile", fs_read_file);
|
|
||||||
methods.add_async_function("readDir", fs_read_dir);
|
|
||||||
methods.add_async_function("writeFile", fs_write_file);
|
|
||||||
methods.add_async_function("writeDir", fs_write_dir);
|
|
||||||
methods.add_async_function("removeFile", fs_remove_file);
|
|
||||||
methods.add_async_function("removeDir", fs_remove_dir);
|
|
||||||
methods.add_async_function("isFile", fs_is_file);
|
|
||||||
methods.add_async_function("isDir", fs_is_dir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_read_file(_: &Lua, path: String) -> Result<String> {
|
async fn fs_read_file(_: &Lua, path: String) -> Result<String> {
|
||||||
|
|
|
@ -4,8 +4,8 @@ mod net;
|
||||||
mod process;
|
mod process;
|
||||||
mod task;
|
mod task;
|
||||||
|
|
||||||
pub use console::Console as ConsoleGlobal;
|
pub use console::new as new_console;
|
||||||
pub use fs::Fs as FsGlobal;
|
pub use fs::new as new_fs;
|
||||||
pub use net::Net as NetGlobal;
|
pub use net::new as new_net;
|
||||||
pub use process::Process as ProcessGlobal;
|
pub use process::new as new_process;
|
||||||
pub use task::Task as TaskGlobal;
|
pub use task::new as new_task;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::HashMap, str::FromStr};
|
use std::{collections::HashMap, str::FromStr};
|
||||||
|
|
||||||
use mlua::{Error, Lua, LuaSerdeExt, Result, UserData, UserDataMethods, Value};
|
use mlua::{Error, Lua, LuaSerdeExt, Result, Table, Value};
|
||||||
use reqwest::{
|
use reqwest::{
|
||||||
header::{HeaderMap, HeaderName, HeaderValue},
|
header::{HeaderMap, HeaderName, HeaderValue},
|
||||||
Method,
|
Method,
|
||||||
|
@ -8,26 +8,13 @@ use reqwest::{
|
||||||
|
|
||||||
use crate::utils::net::get_request_user_agent_header;
|
use crate::utils::net::get_request_user_agent_header;
|
||||||
|
|
||||||
pub struct Net();
|
pub fn new(lua: &Lua) -> Result<Table> {
|
||||||
|
let tab = lua.create_table()?;
|
||||||
impl Net {
|
tab.raw_set("jsonEncode", lua.create_function(net_json_encode)?)?;
|
||||||
pub fn new() -> Self {
|
tab.raw_set("jsonDecode", lua.create_function(net_json_decode)?)?;
|
||||||
Self()
|
tab.raw_set("request", lua.create_async_function(net_request)?)?;
|
||||||
}
|
tab.set_readonly(true);
|
||||||
}
|
Ok(tab)
|
||||||
|
|
||||||
impl Default for Net {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserData for Net {
|
|
||||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
|
||||||
methods.add_function("jsonEncode", net_json_encode);
|
|
||||||
methods.add_function("jsonDecode", net_json_decode);
|
|
||||||
methods.add_async_function("request", net_request);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn net_json_encode(_: &Lua, (val, pretty): (Value, Option<bool>)) -> Result<String> {
|
fn net_json_encode(_: &Lua, (val, pretty): (Value, Option<bool>)) -> Result<String> {
|
||||||
|
|
|
@ -3,66 +3,44 @@ use std::{
|
||||||
process::{exit, Stdio},
|
process::{exit, Stdio},
|
||||||
};
|
};
|
||||||
|
|
||||||
use mlua::{
|
use mlua::{Error, Function, Lua, MetaMethod, Result, Table, Value};
|
||||||
Error, Function, Lua, MetaMethod, Result, Table, UserData, UserDataFields, UserDataMethods,
|
|
||||||
Value,
|
|
||||||
};
|
|
||||||
use os_str_bytes::RawOsString;
|
use os_str_bytes::RawOsString;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
pub struct Process {
|
pub fn new(lua: &Lua, args_vec: Vec<String>) -> Result<Table> {
|
||||||
args: Vec<String>,
|
// Create readonly args array
|
||||||
}
|
let inner_args = lua.create_table()?;
|
||||||
|
for arg in &args_vec {
|
||||||
impl Default for Process {
|
inner_args.push(arg.clone())?;
|
||||||
fn default() -> Self {
|
|
||||||
Self::new(vec![])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Process {
|
|
||||||
pub fn new(args: Vec<String>) -> Self {
|
|
||||||
Self { args }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserData for Process {
|
|
||||||
fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) {
|
|
||||||
fields.add_field_method_get("args", |lua, this| {
|
|
||||||
// TODO: Use the same strategy as env uses below to avoid
|
|
||||||
// copying each time args are accessed? is it worth it?
|
|
||||||
let tab = lua.create_table()?;
|
|
||||||
for arg in &this.args {
|
|
||||||
tab.push(arg.clone())?;
|
|
||||||
}
|
|
||||||
tab.set_readonly(true);
|
|
||||||
Ok(tab)
|
|
||||||
});
|
|
||||||
fields.add_field_method_get("env", |lua, _| {
|
|
||||||
let meta = lua.create_table()?;
|
|
||||||
meta.raw_set(
|
|
||||||
MetaMethod::Index.name(),
|
|
||||||
lua.create_function(process_env_get)?,
|
|
||||||
)?;
|
|
||||||
meta.raw_set(
|
|
||||||
MetaMethod::NewIndex.name(),
|
|
||||||
lua.create_function(process_env_set)?,
|
|
||||||
)?;
|
|
||||||
meta.raw_set(
|
|
||||||
MetaMethod::Iter.name(),
|
|
||||||
lua.create_function(process_env_iter)?,
|
|
||||||
)?;
|
|
||||||
let tab = lua.create_table()?;
|
|
||||||
tab.set_metatable(Some(meta));
|
|
||||||
tab.set_readonly(true);
|
|
||||||
Ok(tab)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
|
||||||
methods.add_function("exit", process_exit);
|
|
||||||
methods.add_async_function("spawn", process_spawn);
|
|
||||||
}
|
}
|
||||||
|
inner_args.set_readonly(true);
|
||||||
|
// Create proxied env metatable that gets & sets real env vars
|
||||||
|
let inner_env_meta = lua.create_table()?;
|
||||||
|
inner_env_meta.raw_set(
|
||||||
|
MetaMethod::Index.name(),
|
||||||
|
lua.create_function(process_env_get)?,
|
||||||
|
)?;
|
||||||
|
inner_env_meta.raw_set(
|
||||||
|
MetaMethod::NewIndex.name(),
|
||||||
|
lua.create_function(process_env_set)?,
|
||||||
|
)?;
|
||||||
|
inner_env_meta.raw_set(
|
||||||
|
MetaMethod::Iter.name(),
|
||||||
|
lua.create_function(process_env_iter)?,
|
||||||
|
)?;
|
||||||
|
inner_env_meta.set_readonly(true);
|
||||||
|
// Create blank table for env with the metatable
|
||||||
|
let inner_env = lua.create_table()?;
|
||||||
|
inner_env.set_metatable(Some(inner_env_meta));
|
||||||
|
inner_env.set_readonly(true);
|
||||||
|
// Create the full process table
|
||||||
|
let tab = lua.create_table()?;
|
||||||
|
tab.raw_set("args", inner_args)?;
|
||||||
|
tab.raw_set("env", inner_env)?;
|
||||||
|
tab.raw_set("exit", lua.create_function(process_exit)?)?;
|
||||||
|
tab.raw_set("spawn", lua.create_async_function(process_spawn)?)?;
|
||||||
|
tab.set_readonly(true);
|
||||||
|
Ok(tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_env_get<'lua>(lua: &'lua Lua, (_, key): (Value<'lua>, String)) -> Result<Value<'lua>> {
|
fn process_env_get<'lua>(lua: &'lua Lua, (_, key): (Value<'lua>, String)) -> Result<Value<'lua>> {
|
||||||
|
|
|
@ -1,36 +1,25 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use mlua::{Function, UserData, UserDataMethods, Value, Variadic};
|
use mlua::{Function, Lua, Result, Table, Value, Variadic};
|
||||||
use tokio::time;
|
use tokio::time;
|
||||||
|
|
||||||
const DEFAULT_SLEEP_DURATION: f32 = 1.0 / 60.0;
|
const DEFAULT_SLEEP_DURATION: f32 = 1.0 / 60.0;
|
||||||
|
|
||||||
pub struct Task();
|
pub fn new(lua: &Lua) -> Result<Table> {
|
||||||
|
let tab = lua.create_table()?;
|
||||||
impl Task {
|
tab.raw_set(
|
||||||
pub fn new() -> Self {
|
"defer",
|
||||||
Self()
|
lua.create_async_function(
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Task {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserData for Task {
|
|
||||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
|
||||||
methods.add_async_function(
|
|
||||||
"defer",
|
|
||||||
|lua, (func, args): (Function, Variadic<Value>)| async move {
|
|lua, (func, args): (Function, Variadic<Value>)| async move {
|
||||||
let thread = lua.create_thread(func)?;
|
let thread = lua.create_thread(func)?;
|
||||||
thread.into_async(args).await?;
|
thread.into_async(args).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
);
|
)?,
|
||||||
methods.add_async_function(
|
)?;
|
||||||
"delay",
|
tab.raw_set(
|
||||||
|
"delay",
|
||||||
|
lua.create_async_function(
|
||||||
|lua, (func, duration, args): (Function, Option<f32>, Variadic<Value>)| async move {
|
|lua, (func, duration, args): (Function, Option<f32>, Variadic<Value>)| async move {
|
||||||
let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION);
|
let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION);
|
||||||
time::sleep(Duration::from_secs_f32(secs)).await;
|
time::sleep(Duration::from_secs_f32(secs)).await;
|
||||||
|
@ -38,19 +27,26 @@ impl UserData for Task {
|
||||||
thread.into_async(args).await?;
|
thread.into_async(args).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
);
|
)?,
|
||||||
methods.add_async_function(
|
)?;
|
||||||
"spawn",
|
tab.raw_set(
|
||||||
|
"spawn",
|
||||||
|
lua.create_async_function(
|
||||||
|lua, (func, args): (Function, Variadic<Value>)| async move {
|
|lua, (func, args): (Function, Variadic<Value>)| async move {
|
||||||
let thread = lua.create_thread(func)?;
|
let thread = lua.create_thread(func)?;
|
||||||
thread.into_async(args).await?;
|
thread.into_async(args).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
);
|
)?,
|
||||||
methods.add_async_function("wait", |_, duration: Option<f32>| async move {
|
)?;
|
||||||
|
tab.raw_set(
|
||||||
|
"wait",
|
||||||
|
lua.create_async_function(|_, duration: Option<f32>| async move {
|
||||||
let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION);
|
let secs = duration.unwrap_or(DEFAULT_SLEEP_DURATION);
|
||||||
time::sleep(Duration::from_secs_f32(secs)).await;
|
time::sleep(Duration::from_secs_f32(secs)).await;
|
||||||
Ok(secs)
|
Ok(secs)
|
||||||
});
|
})?,
|
||||||
}
|
)?;
|
||||||
|
tab.set_readonly(true);
|
||||||
|
Ok(tab)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub mod globals;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
globals::{ConsoleGlobal, FsGlobal, NetGlobal, ProcessGlobal, TaskGlobal},
|
globals::{new_console, new_fs, new_net, new_process, new_task},
|
||||||
utils::formatting::{pretty_print_luau_error, print_label},
|
utils::formatting::{pretty_print_luau_error, print_label},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,11 +29,11 @@ impl Lune {
|
||||||
pub fn with_default_globals(self) -> Result<Self> {
|
pub fn with_default_globals(self) -> Result<Self> {
|
||||||
{
|
{
|
||||||
let globals = self.lua.globals();
|
let globals = self.lua.globals();
|
||||||
globals.raw_set("console", ConsoleGlobal::new())?;
|
globals.raw_set("console", new_console(&self.lua)?)?;
|
||||||
globals.raw_set("fs", FsGlobal::new())?;
|
globals.raw_set("fs", new_fs(&self.lua)?)?;
|
||||||
globals.raw_set("net", NetGlobal::new())?;
|
globals.raw_set("net", new_net(&self.lua)?)?;
|
||||||
globals.raw_set("process", ProcessGlobal::new(self.args.clone()))?;
|
globals.raw_set("process", new_process(&self.lua, self.args.clone())?)?;
|
||||||
globals.raw_set("task", TaskGlobal::new())?;
|
globals.raw_set("task", new_task(&self.lua)?)?;
|
||||||
globals.set_readonly(true);
|
globals.set_readonly(true);
|
||||||
}
|
}
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
|
Loading…
Reference in a new issue