mirror of
https://github.com/lune-org/lune.git
synced 2024-12-13 13:30:38 +00:00
Use table builder wherever possible instead of manual table creation
This commit is contained in:
parent
4ed69994a2
commit
e5e96dfd54
6 changed files with 118 additions and 80 deletions
|
@ -2,7 +2,7 @@ use mlua::{Lua, MultiValue, Result};
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
formatting::{flush_stdout, pretty_format_multi_value, print_color, print_label, print_style},
|
formatting::{flush_stdout, pretty_format_multi_value, print_color, print_label, print_style},
|
||||||
table_builder::ReadonlyTableBuilder,
|
table_builder::TableBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn create(lua: &Lua) -> Result<()> {
|
pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
|
@ -18,7 +18,7 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
};
|
};
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
"console",
|
"console",
|
||||||
ReadonlyTableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_function("resetColor", |_, _: ()| print_color("reset"))?
|
.with_function("resetColor", |_, _: ()| print_color("reset"))?
|
||||||
.with_function("setColor", |_, color: String| print_color(color))?
|
.with_function("setColor", |_, color: String| print_color(color))?
|
||||||
.with_function("resetStyle", |_, _: ()| print_style("reset"))?
|
.with_function("resetStyle", |_, _: ()| print_style("reset"))?
|
||||||
|
@ -39,6 +39,6 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
print_label("error")?;
|
print_label("error")?;
|
||||||
print(&args, true)
|
print(&args, true)
|
||||||
})?
|
})?
|
||||||
.build()?,
|
.build_readonly()?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,12 @@ use std::path::{PathBuf, MAIN_SEPARATOR};
|
||||||
use mlua::{Lua, Result};
|
use mlua::{Lua, Result};
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
use crate::utils::table_builder::ReadonlyTableBuilder;
|
use crate::utils::table_builder::TableBuilder;
|
||||||
|
|
||||||
pub async fn create(lua: &Lua) -> Result<()> {
|
pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
"fs",
|
"fs",
|
||||||
ReadonlyTableBuilder::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)?
|
||||||
.with_async_function("writeFile", fs_write_file)?
|
.with_async_function("writeFile", fs_write_file)?
|
||||||
|
@ -17,7 +17,7 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
.with_async_function("removeDir", fs_remove_dir)?
|
.with_async_function("removeDir", fs_remove_dir)?
|
||||||
.with_async_function("isFile", fs_is_file)?
|
.with_async_function("isFile", fs_is_file)?
|
||||||
.with_async_function("isDir", fs_is_dir)?
|
.with_async_function("isDir", fs_is_dir)?
|
||||||
.build()?,
|
.build_readonly()?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
use std::{collections::HashMap, str::FromStr};
|
use std::{collections::HashMap, str::FromStr};
|
||||||
|
|
||||||
use mlua::{Error, Lua, LuaSerdeExt, Result, Value};
|
use mlua::{Error, Lua, LuaSerdeExt, Result, Table, Value};
|
||||||
use reqwest::{
|
use reqwest::{
|
||||||
header::{HeaderMap, HeaderName, HeaderValue},
|
header::{HeaderMap, HeaderName, HeaderValue},
|
||||||
Method,
|
Method,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::{net::get_request_user_agent_header, table_builder::ReadonlyTableBuilder};
|
use crate::utils::{net::get_request_user_agent_header, table_builder::TableBuilder};
|
||||||
|
|
||||||
pub async fn create(lua: &Lua) -> Result<()> {
|
pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
"net",
|
"net",
|
||||||
ReadonlyTableBuilder::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)?
|
||||||
.with_async_function("request", net_request)?
|
.with_async_function("request", net_request)?
|
||||||
.build()?,
|
.build_readonly()?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ fn net_json_decode(lua: &Lua, json: String) -> Result<Value> {
|
||||||
lua.to_value(&json)
|
lua.to_value(&json)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Value<'lua>> {
|
async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Table<'lua>> {
|
||||||
// Extract stuff from config and make sure its all valid
|
// Extract stuff from config and make sure its all valid
|
||||||
let (url, method, headers, body) = match config {
|
let (url, method, headers, body) = match config {
|
||||||
Value::String(s) => {
|
Value::String(s) => {
|
||||||
|
@ -44,7 +44,11 @@ async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Value<
|
||||||
// Extract url
|
// Extract url
|
||||||
let url = match tab.raw_get::<&str, mlua::String>("url") {
|
let url = match tab.raw_get::<&str, mlua::String>("url") {
|
||||||
Ok(config_url) => config_url.to_string_lossy().to_string(),
|
Ok(config_url) => config_url.to_string_lossy().to_string(),
|
||||||
Err(_) => return Err(Error::RuntimeError("Missing 'url' in config".to_string())),
|
Err(_) => {
|
||||||
|
return Err(Error::RuntimeError(
|
||||||
|
"Missing 'url' in request config".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Extract method
|
// Extract method
|
||||||
let method = match tab.raw_get::<&str, mlua::String>("method") {
|
let method = match tab.raw_get::<&str, mlua::String>("method") {
|
||||||
|
@ -73,14 +77,19 @@ async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Value<
|
||||||
};
|
};
|
||||||
(url, method, headers, body)
|
(url, method, headers, body)
|
||||||
}
|
}
|
||||||
_ => return Err(Error::RuntimeError("Invalid config value".to_string())),
|
value => {
|
||||||
|
return Err(Error::RuntimeError(format!(
|
||||||
|
"Invalid request config - expected string or table, got {}",
|
||||||
|
value.type_name()
|
||||||
|
)))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Convert method string into proper enum
|
// Convert method string into proper enum
|
||||||
let method = match Method::from_str(&method) {
|
let method = match Method::from_str(&method) {
|
||||||
Ok(meth) => meth,
|
Ok(meth) => meth,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Err(Error::RuntimeError(format!(
|
return Err(Error::RuntimeError(format!(
|
||||||
"Invalid config method '{}'",
|
"Invalid request config method '{}'",
|
||||||
&method
|
&method
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
@ -111,22 +120,23 @@ async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Value<
|
||||||
let res_headers = response.headers().clone();
|
let res_headers = response.headers().clone();
|
||||||
let res_bytes = response.bytes().await.map_err(Error::external)?;
|
let res_bytes = response.bytes().await.map_err(Error::external)?;
|
||||||
// Construct and return a readonly lua table with results
|
// Construct and return a readonly lua table with results
|
||||||
let tab = lua.create_table()?;
|
TableBuilder::new(lua)?
|
||||||
tab.raw_set("ok", res_status.is_success())?;
|
.with_value("ok", res_status.is_success())?
|
||||||
tab.raw_set("statusCode", res_status.as_u16())?;
|
.with_value("statusCode", res_status.as_u16())?
|
||||||
tab.raw_set(
|
.with_value(
|
||||||
"statusMessage",
|
"statusMessage",
|
||||||
res_status.canonical_reason().unwrap_or("?"),
|
res_status.canonical_reason().unwrap_or("?"),
|
||||||
)?;
|
)?
|
||||||
tab.raw_set(
|
.with_value(
|
||||||
"headers",
|
"headers",
|
||||||
res_headers
|
res_headers
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, value)| value.to_str().is_ok())
|
.filter_map(|(key, value)| match value.to_str() {
|
||||||
.map(|(key, value)| (key.as_str(), value.to_str().unwrap()))
|
Ok(value) => Some((key.as_str(), value)),
|
||||||
|
Err(_) => None,
|
||||||
|
})
|
||||||
.collect::<HashMap<_, _>>(),
|
.collect::<HashMap<_, _>>(),
|
||||||
)?;
|
)?
|
||||||
tab.raw_set("body", lua.create_string(&res_bytes)?)?;
|
.with_value("body", lua.create_string(&res_bytes)?)?
|
||||||
tab.set_readonly(true);
|
.build_readonly()
|
||||||
Ok(Value::Table(tab))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,43 +7,32 @@ use mlua::{Error, Function, Lua, MetaMethod, Result, Table, Value};
|
||||||
use os_str_bytes::RawOsString;
|
use os_str_bytes::RawOsString;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
use crate::utils::table_builder::ReadonlyTableBuilder;
|
use crate::utils::table_builder::TableBuilder;
|
||||||
|
|
||||||
pub async fn create(lua: &Lua, args_vec: Vec<String>) -> Result<()> {
|
pub async fn create(lua: &Lua, args_vec: Vec<String>) -> Result<()> {
|
||||||
// Create readonly args array
|
// Create readonly args array
|
||||||
let inner_args = lua.create_table()?;
|
let args_tab = TableBuilder::new(lua)?
|
||||||
for arg in &args_vec {
|
.with_sequential_values(args_vec)?
|
||||||
inner_args.push(arg.clone())?;
|
.build_readonly()?;
|
||||||
}
|
// Create proxied table for env that gets & sets real env vars
|
||||||
inner_args.set_readonly(true);
|
let env_tab = TableBuilder::new(lua)?
|
||||||
// Create proxied env metatable that gets & sets real env vars
|
.with_metatable(
|
||||||
let inner_env_meta = lua.create_table()?;
|
TableBuilder::new(lua)?
|
||||||
inner_env_meta.raw_set(
|
.with_function(MetaMethod::Index.name(), process_env_get)?
|
||||||
MetaMethod::Index.name(),
|
.with_function(MetaMethod::NewIndex.name(), process_env_set)?
|
||||||
lua.create_function(process_env_get)?,
|
.with_function(MetaMethod::Iter.name(), process_env_iter)?
|
||||||
)?;
|
.build_readonly()?,
|
||||||
inner_env_meta.raw_set(
|
)?
|
||||||
MetaMethod::NewIndex.name(),
|
.build_readonly()?;
|
||||||
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
|
// Create the full process table
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
"process",
|
"process",
|
||||||
ReadonlyTableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_table("args", inner_args)?
|
.with_value("args", args_tab)?
|
||||||
.with_table("env", inner_env)?
|
.with_value("env", env_tab)?
|
||||||
.with_function("exit", process_exit)?
|
.with_function("exit", process_exit)?
|
||||||
.with_async_function("spawn", process_spawn)?
|
.with_async_function("spawn", process_spawn)?
|
||||||
.build()?,
|
.build_readonly()?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,11 +127,10 @@ async fn process_spawn(lua: &Lua, (program, args): (String, Option<Vec<String>>)
|
||||||
false => 1,
|
false => 1,
|
||||||
});
|
});
|
||||||
// Construct and return a readonly lua table with results
|
// Construct and return a readonly lua table with results
|
||||||
let table = lua.create_table()?;
|
TableBuilder::new(lua)?
|
||||||
table.raw_set("ok", code == 0)?;
|
.with_value("ok", code == 0)?
|
||||||
table.raw_set("code", code)?;
|
.with_value("code", code)?
|
||||||
table.raw_set("stdout", lua.create_string(&output.stdout)?)?;
|
.with_value("stdout", lua.create_string(&output.stdout)?)?
|
||||||
table.raw_set("stderr", lua.create_string(&output.stderr)?)?;
|
.with_value("stderr", lua.create_string(&output.stderr)?)?
|
||||||
table.set_readonly(true);
|
.build_readonly()
|
||||||
Ok(table)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,20 @@ use std::time::Duration;
|
||||||
use mlua::{Error, Function, Lua, Result, Table, Thread, Value, Variadic};
|
use mlua::{Error, Function, Lua, Result, Table, Thread, Value, Variadic};
|
||||||
use tokio::time::{self, Instant};
|
use tokio::time::{self, Instant};
|
||||||
|
|
||||||
use crate::utils::table_builder::ReadonlyTableBuilder;
|
use crate::utils::table_builder::TableBuilder;
|
||||||
|
|
||||||
type Vararg<'lua> = Variadic<Value<'lua>>;
|
type Vararg<'lua> = Variadic<Value<'lua>>;
|
||||||
|
|
||||||
pub async fn create(lua: &Lua) -> Result<()> {
|
pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
"task",
|
"task",
|
||||||
ReadonlyTableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_async_function("cancel", task_cancel)?
|
.with_async_function("cancel", task_cancel)?
|
||||||
.with_async_function("defer", task_defer)?
|
.with_async_function("defer", task_defer)?
|
||||||
.with_async_function("delay", task_delay)?
|
.with_async_function("delay", task_delay)?
|
||||||
.with_async_function("spawn", task_spawn)?
|
.with_async_function("spawn", task_spawn)?
|
||||||
.with_async_function("wait", task_wait)?
|
.with_async_function("wait", task_wait)?
|
||||||
.build()?,
|
.build_readonly()?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,64 @@
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
use mlua::{FromLuaMulti, Lua, Result, Table, ToLuaMulti, Value};
|
use mlua::{FromLuaMulti, Lua, Result, Table, ToLua, ToLuaMulti, Value};
|
||||||
|
|
||||||
pub struct ReadonlyTableBuilder<'lua> {
|
pub struct TableBuilder<'lua> {
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
tab: Table<'lua>,
|
tab: Table<'lua>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> ReadonlyTableBuilder<'lua> {
|
impl<'lua> TableBuilder<'lua> {
|
||||||
pub fn new(lua: &'lua Lua) -> Result<Self> {
|
pub fn new(lua: &'lua Lua) -> Result<Self> {
|
||||||
let tab = lua.create_table()?;
|
let tab = lua.create_table()?;
|
||||||
Ok(Self { lua, tab })
|
Ok(Self { lua, tab })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_value(self, key: &'static str, value: Value) -> Result<Self> {
|
pub fn with_value<K, V>(self, key: K, value: V) -> Result<Self>
|
||||||
|
where
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
V: ToLua<'lua>,
|
||||||
|
{
|
||||||
self.tab.raw_set(key, value)?;
|
self.tab.raw_set(key, value)?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_table(self, key: &'static str, table: Table) -> Result<Self> {
|
pub fn with_values<K, V>(self, values: Vec<(K, V)>) -> Result<Self>
|
||||||
self.with_value(key, Value::Table(table))
|
where
|
||||||
|
K: ToLua<'lua>,
|
||||||
|
V: ToLua<'lua>,
|
||||||
|
{
|
||||||
|
for (key, value) in values {
|
||||||
|
self.tab.raw_set(key, value)?;
|
||||||
|
}
|
||||||
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_function<A, R, F>(self, key: &'static str, func: F) -> Result<Self>
|
pub fn with_sequential_value<V>(self, value: V) -> Result<Self>
|
||||||
where
|
where
|
||||||
|
V: ToLua<'lua>,
|
||||||
|
{
|
||||||
|
self.tab.raw_push(value)?;
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_sequential_values<V>(self, values: Vec<V>) -> Result<Self>
|
||||||
|
where
|
||||||
|
V: ToLua<'lua>,
|
||||||
|
{
|
||||||
|
for value in values {
|
||||||
|
self.tab.raw_push(value)?;
|
||||||
|
}
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_metatable(self, table: Table) -> Result<Self> {
|
||||||
|
self.tab.set_metatable(Some(table));
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_function<K, A, R, F>(self, key: K, func: F) -> Result<Self>
|
||||||
|
where
|
||||||
|
K: ToLua<'lua>,
|
||||||
A: FromLuaMulti<'lua>,
|
A: FromLuaMulti<'lua>,
|
||||||
R: ToLuaMulti<'lua>,
|
R: ToLuaMulti<'lua>,
|
||||||
F: 'static + Fn(&'lua Lua, A) -> Result<R>,
|
F: 'static + Fn(&'lua Lua, A) -> Result<R>,
|
||||||
|
@ -32,8 +67,9 @@ impl<'lua> ReadonlyTableBuilder<'lua> {
|
||||||
self.with_value(key, Value::Function(f))
|
self.with_value(key, Value::Function(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_async_function<A, R, F, FR>(self, key: &'static str, func: F) -> Result<Self>
|
pub fn with_async_function<K, A, R, F, FR>(self, key: K, func: F) -> Result<Self>
|
||||||
where
|
where
|
||||||
|
K: ToLua<'lua>,
|
||||||
A: FromLuaMulti<'lua>,
|
A: FromLuaMulti<'lua>,
|
||||||
R: ToLuaMulti<'lua>,
|
R: ToLuaMulti<'lua>,
|
||||||
F: 'static + Fn(&'lua Lua, A) -> FR,
|
F: 'static + Fn(&'lua Lua, A) -> FR,
|
||||||
|
@ -43,8 +79,12 @@ impl<'lua> ReadonlyTableBuilder<'lua> {
|
||||||
self.with_value(key, Value::Function(f))
|
self.with_value(key, Value::Function(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Result<Table<'lua>> {
|
pub fn build_readonly(self) -> Result<Table<'lua>> {
|
||||||
self.tab.set_readonly(true);
|
self.tab.set_readonly(true);
|
||||||
Ok(self.tab)
|
Ok(self.tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build(self) -> Result<Table<'lua>> {
|
||||||
|
Ok(self.tab)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue