mirror of
https://github.com/lune-org/lune.git
synced 2024-12-13 05:20:37 +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::{
|
||||
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<()> {
|
||||
|
@ -18,7 +18,7 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
|||
};
|
||||
lua.globals().raw_set(
|
||||
"console",
|
||||
ReadonlyTableBuilder::new(lua)?
|
||||
TableBuilder::new(lua)?
|
||||
.with_function("resetColor", |_, _: ()| print_color("reset"))?
|
||||
.with_function("setColor", |_, color: String| print_color(color))?
|
||||
.with_function("resetStyle", |_, _: ()| print_style("reset"))?
|
||||
|
@ -39,6 +39,6 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
|||
print_label("error")?;
|
||||
print(&args, true)
|
||||
})?
|
||||
.build()?,
|
||||
.build_readonly()?,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@ use std::path::{PathBuf, MAIN_SEPARATOR};
|
|||
use mlua::{Lua, Result};
|
||||
use tokio::fs;
|
||||
|
||||
use crate::utils::table_builder::ReadonlyTableBuilder;
|
||||
use crate::utils::table_builder::TableBuilder;
|
||||
|
||||
pub async fn create(lua: &Lua) -> Result<()> {
|
||||
lua.globals().raw_set(
|
||||
"fs",
|
||||
ReadonlyTableBuilder::new(lua)?
|
||||
TableBuilder::new(lua)?
|
||||
.with_async_function("readFile", fs_read_file)?
|
||||
.with_async_function("readDir", fs_read_dir)?
|
||||
.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("isFile", fs_is_file)?
|
||||
.with_async_function("isDir", fs_is_dir)?
|
||||
.build()?,
|
||||
.build_readonly()?,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use mlua::{Error, Lua, LuaSerdeExt, Result, Value};
|
||||
use mlua::{Error, Lua, LuaSerdeExt, Result, Table, Value};
|
||||
use reqwest::{
|
||||
header::{HeaderMap, HeaderName, HeaderValue},
|
||||
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<()> {
|
||||
lua.globals().raw_set(
|
||||
"net",
|
||||
ReadonlyTableBuilder::new(lua)?
|
||||
TableBuilder::new(lua)?
|
||||
.with_function("jsonEncode", net_json_encode)?
|
||||
.with_function("jsonDecode", net_json_decode)?
|
||||
.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)
|
||||
}
|
||||
|
||||
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
|
||||
let (url, method, headers, body) = match config {
|
||||
Value::String(s) => {
|
||||
|
@ -44,7 +44,11 @@ async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Value<
|
|||
// Extract url
|
||||
let url = match tab.raw_get::<&str, mlua::String>("url") {
|
||||
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
|
||||
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)
|
||||
}
|
||||
_ => 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
|
||||
let method = match Method::from_str(&method) {
|
||||
Ok(meth) => meth,
|
||||
Err(_) => {
|
||||
return Err(Error::RuntimeError(format!(
|
||||
"Invalid config method '{}'",
|
||||
"Invalid request config 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_bytes = response.bytes().await.map_err(Error::external)?;
|
||||
// Construct and return a readonly lua table with results
|
||||
let tab = lua.create_table()?;
|
||||
tab.raw_set("ok", res_status.is_success())?;
|
||||
tab.raw_set("statusCode", res_status.as_u16())?;
|
||||
tab.raw_set(
|
||||
"statusMessage",
|
||||
res_status.canonical_reason().unwrap_or("?"),
|
||||
)?;
|
||||
tab.raw_set(
|
||||
"headers",
|
||||
res_headers
|
||||
.iter()
|
||||
.filter(|(_, value)| value.to_str().is_ok())
|
||||
.map(|(key, value)| (key.as_str(), value.to_str().unwrap()))
|
||||
.collect::<HashMap<_, _>>(),
|
||||
)?;
|
||||
tab.raw_set("body", lua.create_string(&res_bytes)?)?;
|
||||
tab.set_readonly(true);
|
||||
Ok(Value::Table(tab))
|
||||
TableBuilder::new(lua)?
|
||||
.with_value("ok", res_status.is_success())?
|
||||
.with_value("statusCode", res_status.as_u16())?
|
||||
.with_value(
|
||||
"statusMessage",
|
||||
res_status.canonical_reason().unwrap_or("?"),
|
||||
)?
|
||||
.with_value(
|
||||
"headers",
|
||||
res_headers
|
||||
.iter()
|
||||
.filter_map(|(key, value)| match value.to_str() {
|
||||
Ok(value) => Some((key.as_str(), value)),
|
||||
Err(_) => None,
|
||||
})
|
||||
.collect::<HashMap<_, _>>(),
|
||||
)?
|
||||
.with_value("body", lua.create_string(&res_bytes)?)?
|
||||
.build_readonly()
|
||||
}
|
||||
|
|
|
@ -7,43 +7,32 @@ use mlua::{Error, Function, Lua, MetaMethod, Result, Table, Value};
|
|||
use os_str_bytes::RawOsString;
|
||||
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<()> {
|
||||
// Create readonly args array
|
||||
let inner_args = lua.create_table()?;
|
||||
for arg in &args_vec {
|
||||
inner_args.push(arg.clone())?;
|
||||
}
|
||||
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);
|
||||
let args_tab = TableBuilder::new(lua)?
|
||||
.with_sequential_values(args_vec)?
|
||||
.build_readonly()?;
|
||||
// Create proxied table for env that gets & sets real env vars
|
||||
let env_tab = TableBuilder::new(lua)?
|
||||
.with_metatable(
|
||||
TableBuilder::new(lua)?
|
||||
.with_function(MetaMethod::Index.name(), process_env_get)?
|
||||
.with_function(MetaMethod::NewIndex.name(), process_env_set)?
|
||||
.with_function(MetaMethod::Iter.name(), process_env_iter)?
|
||||
.build_readonly()?,
|
||||
)?
|
||||
.build_readonly()?;
|
||||
// Create the full process table
|
||||
lua.globals().raw_set(
|
||||
"process",
|
||||
ReadonlyTableBuilder::new(lua)?
|
||||
.with_table("args", inner_args)?
|
||||
.with_table("env", inner_env)?
|
||||
TableBuilder::new(lua)?
|
||||
.with_value("args", args_tab)?
|
||||
.with_value("env", env_tab)?
|
||||
.with_function("exit", process_exit)?
|
||||
.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,
|
||||
});
|
||||
// Construct and return a readonly lua table with results
|
||||
let table = lua.create_table()?;
|
||||
table.raw_set("ok", code == 0)?;
|
||||
table.raw_set("code", code)?;
|
||||
table.raw_set("stdout", lua.create_string(&output.stdout)?)?;
|
||||
table.raw_set("stderr", lua.create_string(&output.stderr)?)?;
|
||||
table.set_readonly(true);
|
||||
Ok(table)
|
||||
TableBuilder::new(lua)?
|
||||
.with_value("ok", code == 0)?
|
||||
.with_value("code", code)?
|
||||
.with_value("stdout", lua.create_string(&output.stdout)?)?
|
||||
.with_value("stderr", lua.create_string(&output.stderr)?)?
|
||||
.build_readonly()
|
||||
}
|
||||
|
|
|
@ -3,20 +3,20 @@ use std::time::Duration;
|
|||
use mlua::{Error, Function, Lua, Result, Table, Thread, Value, Variadic};
|
||||
use tokio::time::{self, Instant};
|
||||
|
||||
use crate::utils::table_builder::ReadonlyTableBuilder;
|
||||
use crate::utils::table_builder::TableBuilder;
|
||||
|
||||
type Vararg<'lua> = Variadic<Value<'lua>>;
|
||||
|
||||
pub async fn create(lua: &Lua) -> Result<()> {
|
||||
lua.globals().raw_set(
|
||||
"task",
|
||||
ReadonlyTableBuilder::new(lua)?
|
||||
TableBuilder::new(lua)?
|
||||
.with_async_function("cancel", task_cancel)?
|
||||
.with_async_function("defer", task_defer)?
|
||||
.with_async_function("delay", task_delay)?
|
||||
.with_async_function("spawn", task_spawn)?
|
||||
.with_async_function("wait", task_wait)?
|
||||
.build()?,
|
||||
.build_readonly()?,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,64 @@
|
|||
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,
|
||||
tab: Table<'lua>,
|
||||
}
|
||||
|
||||
impl<'lua> ReadonlyTableBuilder<'lua> {
|
||||
impl<'lua> TableBuilder<'lua> {
|
||||
pub fn new(lua: &'lua Lua) -> Result<Self> {
|
||||
let tab = lua.create_table()?;
|
||||
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)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn with_table(self, key: &'static str, table: Table) -> Result<Self> {
|
||||
self.with_value(key, Value::Table(table))
|
||||
pub fn with_values<K, V>(self, values: Vec<(K, V)>) -> Result<Self>
|
||||
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
|
||||
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>,
|
||||
R: ToLuaMulti<'lua>,
|
||||
F: 'static + Fn(&'lua Lua, A) -> Result<R>,
|
||||
|
@ -32,8 +67,9 @@ impl<'lua> ReadonlyTableBuilder<'lua> {
|
|||
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
|
||||
K: ToLua<'lua>,
|
||||
A: FromLuaMulti<'lua>,
|
||||
R: ToLuaMulti<'lua>,
|
||||
F: 'static + Fn(&'lua Lua, A) -> FR,
|
||||
|
@ -43,8 +79,12 @@ impl<'lua> ReadonlyTableBuilder<'lua> {
|
|||
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);
|
||||
Ok(self.tab)
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<Table<'lua>> {
|
||||
Ok(self.tab)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue