mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 21:10:36 +00:00
Use mlua prelude instead of manual imports
This commit is contained in:
parent
09a7619995
commit
d531cf3813
8 changed files with 160 additions and 146 deletions
|
@ -2,6 +2,7 @@ use std::fs::read_to_string;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::{CommandFactory, Parser};
|
use clap::{CommandFactory, Parser};
|
||||||
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use lune::Lune;
|
use lune::Lune;
|
||||||
|
|
||||||
|
@ -61,20 +62,20 @@ impl Cli {
|
||||||
let release = client
|
let release = client
|
||||||
.fetch_release_for_this_version()
|
.fetch_release_for_this_version()
|
||||||
.await
|
.await
|
||||||
.map_err(mlua::Error::external)?;
|
.map_err(LuaError::external)?;
|
||||||
if self.download_selene_types {
|
if self.download_selene_types {
|
||||||
println!("Downloading Selene type definitions...");
|
println!("Downloading Selene type definitions...");
|
||||||
client
|
client
|
||||||
.fetch_release_asset(&release, "lune.yml")
|
.fetch_release_asset(&release, "lune.yml")
|
||||||
.await
|
.await
|
||||||
.map_err(mlua::Error::external)?;
|
.map_err(LuaError::external)?;
|
||||||
}
|
}
|
||||||
if self.download_luau_types {
|
if self.download_luau_types {
|
||||||
println!("Downloading Luau type definitions...");
|
println!("Downloading Luau type definitions...");
|
||||||
client
|
client
|
||||||
.fetch_release_asset(&release, "luneTypes.d.luau")
|
.fetch_release_asset(&release, "luneTypes.d.luau")
|
||||||
.await
|
.await
|
||||||
.map_err(mlua::Error::external)?;
|
.map_err(LuaError::external)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.script_path.is_none() {
|
if self.script_path.is_none() {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use mlua::{Lua, MultiValue, Result};
|
use mlua::prelude::*;
|
||||||
|
|
||||||
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::TableBuilder,
|
table_builder::TableBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn create(lua: &Lua) -> Result<()> {
|
pub async fn create(lua: &Lua) -> LuaResult<()> {
|
||||||
let print = |args: &MultiValue, throw: bool| -> Result<()> {
|
let print = |args: &LuaMultiValue, throw: bool| -> LuaResult<()> {
|
||||||
let s = pretty_format_multi_value(args)?;
|
let s = pretty_format_multi_value(args)?;
|
||||||
if throw {
|
if throw {
|
||||||
eprintln!("{s}");
|
eprintln!("{s}");
|
||||||
|
@ -23,19 +23,19 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
.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"))?
|
||||||
.with_function("setStyle", |_, style: String| print_style(style))?
|
.with_function("setStyle", |_, style: String| print_style(style))?
|
||||||
.with_function("format", |_, args: MultiValue| {
|
.with_function("format", |_, args: LuaMultiValue| {
|
||||||
pretty_format_multi_value(&args)
|
pretty_format_multi_value(&args)
|
||||||
})?
|
})?
|
||||||
.with_function("log", move |_, args: MultiValue| print(&args, false))?
|
.with_function("log", move |_, args: LuaMultiValue| print(&args, false))?
|
||||||
.with_function("info", move |_, args: MultiValue| {
|
.with_function("info", move |_, args: LuaMultiValue| {
|
||||||
print_label("info")?;
|
print_label("info")?;
|
||||||
print(&args, false)
|
print(&args, false)
|
||||||
})?
|
})?
|
||||||
.with_function("warn", move |_, args: MultiValue| {
|
.with_function("warn", move |_, args: LuaMultiValue| {
|
||||||
print_label("warn")?;
|
print_label("warn")?;
|
||||||
print(&args, false)
|
print(&args, false)
|
||||||
})?
|
})?
|
||||||
.with_function("error", move |_, args: MultiValue| {
|
.with_function("error", move |_, args: LuaMultiValue| {
|
||||||
print_label("error")?;
|
print_label("error")?;
|
||||||
print(&args, true)
|
print(&args, true)
|
||||||
})?
|
})?
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::path::{PathBuf, MAIN_SEPARATOR};
|
use std::path::{PathBuf, MAIN_SEPARATOR};
|
||||||
|
|
||||||
use mlua::{Lua, Result};
|
use mlua::prelude::*;
|
||||||
use smol::{fs, prelude::*};
|
use smol::{fs, prelude::*};
|
||||||
|
|
||||||
use crate::utils::table_builder::TableBuilder;
|
use crate::utils::table_builder::TableBuilder;
|
||||||
|
|
||||||
pub async fn create(lua: &Lua) -> Result<()> {
|
pub async fn create(lua: &Lua) -> LuaResult<()> {
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
"fs",
|
"fs",
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
|
@ -21,20 +21,18 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_read_file(_: &Lua, path: String) -> Result<String> {
|
async fn fs_read_file(_: &Lua, path: String) -> LuaResult<String> {
|
||||||
fs::read_to_string(&path)
|
fs::read_to_string(&path).await.map_err(LuaError::external)
|
||||||
.await
|
|
||||||
.map_err(mlua::Error::external)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_read_dir(_: &Lua, path: String) -> Result<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.map_err(mlua::Error::external)?;
|
let mut dir = fs::read_dir(&path).await.map_err(LuaError::external)?;
|
||||||
while let Some(dir_entry) = dir.try_next().await.map_err(mlua::Error::external)? {
|
while let Some(dir_entry) = dir.try_next().await.map_err(LuaError::external)? {
|
||||||
if let Some(dir_path_str) = dir_entry.path().to_str() {
|
if let Some(dir_path_str) = dir_entry.path().to_str() {
|
||||||
dir_strings.push(dir_path_str.to_owned());
|
dir_strings.push(dir_path_str.to_owned());
|
||||||
} else {
|
} else {
|
||||||
return Err(mlua::Error::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"File path could not be converted into a string: '{}'",
|
"File path could not be converted into a string: '{}'",
|
||||||
dir_entry.path().display()
|
dir_entry.path().display()
|
||||||
)));
|
)));
|
||||||
|
@ -57,46 +55,42 @@ async fn fs_read_dir(_: &Lua, path: String) -> Result<Vec<String>> {
|
||||||
Ok(dir_strings_no_prefix)
|
Ok(dir_strings_no_prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_write_file(_: &Lua, (path, contents): (String, String)) -> Result<()> {
|
async fn fs_write_file(_: &Lua, (path, contents): (String, String)) -> LuaResult<()> {
|
||||||
fs::write(&path, &contents)
|
fs::write(&path, &contents)
|
||||||
.await
|
.await
|
||||||
.map_err(mlua::Error::external)
|
.map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_write_dir(_: &Lua, path: String) -> Result<()> {
|
async fn fs_write_dir(_: &Lua, path: String) -> LuaResult<()> {
|
||||||
fs::create_dir_all(&path)
|
fs::create_dir_all(&path).await.map_err(LuaError::external)
|
||||||
.await
|
|
||||||
.map_err(mlua::Error::external)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_remove_file(_: &Lua, path: String) -> Result<()> {
|
async fn fs_remove_file(_: &Lua, path: String) -> LuaResult<()> {
|
||||||
fs::remove_file(&path).await.map_err(mlua::Error::external)
|
fs::remove_file(&path).await.map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_remove_dir(_: &Lua, path: String) -> Result<()> {
|
async fn fs_remove_dir(_: &Lua, path: String) -> LuaResult<()> {
|
||||||
fs::remove_dir_all(&path)
|
fs::remove_dir_all(&path).await.map_err(LuaError::external)
|
||||||
.await
|
|
||||||
.map_err(mlua::Error::external)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_is_file(_: &Lua, path: String) -> Result<bool> {
|
async fn fs_is_file(_: &Lua, path: String) -> LuaResult<bool> {
|
||||||
let path = PathBuf::from(path);
|
let path = PathBuf::from(path);
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
Ok(fs::metadata(path)
|
Ok(fs::metadata(path)
|
||||||
.await
|
.await
|
||||||
.map_err(mlua::Error::external)?
|
.map_err(LuaError::external)?
|
||||||
.is_file())
|
.is_file())
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fs_is_dir(_: &Lua, path: String) -> Result<bool> {
|
async fn fs_is_dir(_: &Lua, path: String) -> LuaResult<bool> {
|
||||||
let path = PathBuf::from(path);
|
let path = PathBuf::from(path);
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
Ok(fs::metadata(path)
|
Ok(fs::metadata(path)
|
||||||
.await
|
.await
|
||||||
.map_err(mlua::Error::external)?
|
.map_err(LuaError::external)?
|
||||||
.is_dir())
|
.is_dir())
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use mlua::{Error, Lua, LuaSerdeExt, Result, Table, Value};
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::utils::{net::get_request_user_agent_header, table_builder::TableBuilder};
|
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) -> LuaResult<()> {
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
"net",
|
"net",
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
|
@ -15,45 +15,45 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn net_json_encode(_: &Lua, (val, pretty): (Value, Option<bool>)) -> Result<String> {
|
fn net_json_encode(_: &Lua, (val, pretty): (LuaValue, Option<bool>)) -> LuaResult<String> {
|
||||||
if let Some(true) = pretty {
|
if let Some(true) = pretty {
|
||||||
serde_json::to_string_pretty(&val).map_err(Error::external)
|
serde_json::to_string_pretty(&val).map_err(LuaError::external)
|
||||||
} else {
|
} else {
|
||||||
serde_json::to_string(&val).map_err(Error::external)
|
serde_json::to_string(&val).map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn net_json_decode(lua: &Lua, json: String) -> Result<Value> {
|
fn net_json_decode(lua: &Lua, json: String) -> LuaResult<LuaValue> {
|
||||||
let json: serde_json::Value = serde_json::from_str(&json).map_err(Error::external)?;
|
let json: serde_json::Value = serde_json::from_str(&json).map_err(LuaError::external)?;
|
||||||
lua.to_value(&json)
|
lua.to_value(&json)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Table<'lua>> {
|
async fn net_request<'lua>(lua: &'lua Lua, config: LuaValue<'lua>) -> LuaResult<LuaTable<'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) => {
|
LuaValue::String(s) => {
|
||||||
let url = s.to_string_lossy().to_string();
|
let url = s.to_string_lossy().to_string();
|
||||||
let method = "GET".to_string();
|
let method = "GET".to_string();
|
||||||
Ok((url, method, HashMap::new(), None))
|
Ok((url, method, HashMap::new(), None))
|
||||||
}
|
}
|
||||||
Value::Table(tab) => {
|
LuaValue::Table(tab) => {
|
||||||
// Extract url
|
// Extract url
|
||||||
let url = match tab.raw_get::<&str, mlua::String>("url") {
|
let url = match tab.raw_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(Error::RuntimeError(
|
Err(_) => Err(LuaError::RuntimeError(
|
||||||
"Missing 'url' in request config".to_string(),
|
"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::<_, 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 headers
|
// Extract headers
|
||||||
let headers = match tab.raw_get::<&str, mlua::Table>("headers") {
|
let headers = match tab.raw_get::<_, LuaTable>("headers") {
|
||||||
Ok(config_headers) => {
|
Ok(config_headers) => {
|
||||||
let mut lua_headers = HashMap::new();
|
let mut lua_headers = HashMap::new();
|
||||||
for pair in config_headers.pairs::<mlua::String, mlua::String>() {
|
for pair in config_headers.pairs::<LuaString, LuaString>() {
|
||||||
let (key, value) = pair?.to_owned();
|
let (key, value) = pair?.to_owned();
|
||||||
lua_headers.insert(key, value);
|
lua_headers.insert(key, value);
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,13 @@ async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Table<
|
||||||
Err(_) => HashMap::new(),
|
Err(_) => HashMap::new(),
|
||||||
};
|
};
|
||||||
// Extract body
|
// Extract body
|
||||||
let body = match tab.raw_get::<&str, mlua::String>("body") {
|
let body = match tab.raw_get::<_, LuaString>("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,
|
||||||
};
|
};
|
||||||
Ok((url, method, headers, body))
|
Ok((url, method, headers, body))
|
||||||
}
|
}
|
||||||
value => Err(Error::RuntimeError(format!(
|
value => Err(LuaError::RuntimeError(format!(
|
||||||
"Invalid request config - expected string or table, got {}",
|
"Invalid request config - expected string or table, got {}",
|
||||||
value.type_name()
|
value.type_name()
|
||||||
))),
|
))),
|
||||||
|
@ -77,7 +77,7 @@ async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Table<
|
||||||
let method = method.trim().to_ascii_uppercase();
|
let method = method.trim().to_ascii_uppercase();
|
||||||
let method = match method.as_ref() {
|
let method = match method.as_ref() {
|
||||||
"GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH" => Ok(&method),
|
"GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH" => Ok(&method),
|
||||||
_ => Err(Error::RuntimeError(format!(
|
_ => Err(LuaError::RuntimeError(format!(
|
||||||
"Invalid request config method '{}'",
|
"Invalid request config method '{}'",
|
||||||
&method
|
&method
|
||||||
))),
|
))),
|
||||||
|
@ -112,6 +112,6 @@ async fn net_request<'lua>(lua: &'lua Lua, config: Value<'lua>) -> Result<Table<
|
||||||
.with_value("body", lua.create_string(&res_bytes)?)?
|
.with_value("body", lua.create_string(&res_bytes)?)?
|
||||||
.build_readonly()
|
.build_readonly()
|
||||||
}
|
}
|
||||||
Err(e) => Err(Error::external(e)),
|
Err(e) => Err(LuaError::external(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ use std::{
|
||||||
process::{exit, Stdio},
|
process::{exit, Stdio},
|
||||||
};
|
};
|
||||||
|
|
||||||
use mlua::{Error, Function, Lua, MetaMethod, Result, Table, Value};
|
use mlua::prelude::*;
|
||||||
use os_str_bytes::RawOsString;
|
use os_str_bytes::RawOsString;
|
||||||
use smol::process::Command;
|
use smol::process::Command;
|
||||||
|
|
||||||
use crate::utils::table_builder::TableBuilder;
|
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>) -> LuaResult<()> {
|
||||||
// Create readonly args array
|
// Create readonly args array
|
||||||
let args_tab = TableBuilder::new(lua)?
|
let args_tab = TableBuilder::new(lua)?
|
||||||
.with_sequential_values(args_vec)?
|
.with_sequential_values(args_vec)?
|
||||||
|
@ -18,9 +18,9 @@ pub async fn create(lua: &Lua, args_vec: Vec<String>) -> Result<()> {
|
||||||
let env_tab = TableBuilder::new(lua)?
|
let env_tab = TableBuilder::new(lua)?
|
||||||
.with_metatable(
|
.with_metatable(
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_function(MetaMethod::Index.name(), process_env_get)?
|
.with_function(LuaMetaMethod::Index.name(), process_env_get)?
|
||||||
.with_function(MetaMethod::NewIndex.name(), process_env_set)?
|
.with_function(LuaMetaMethod::NewIndex.name(), process_env_set)?
|
||||||
.with_function(MetaMethod::Iter.name(), process_env_iter)?
|
.with_function(LuaMetaMethod::Iter.name(), process_env_iter)?
|
||||||
.build_readonly()?,
|
.build_readonly()?,
|
||||||
)?
|
)?
|
||||||
.build_readonly()?;
|
.build_readonly()?;
|
||||||
|
@ -36,26 +36,31 @@ pub async fn create(lua: &Lua, args_vec: Vec<String>) -> Result<()> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_env_get<'lua>(lua: &'lua Lua, (_, key): (Value<'lua>, String)) -> Result<Value<'lua>> {
|
fn process_env_get<'lua>(
|
||||||
|
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);
|
||||||
Ok(Value::String(lua.create_string(raw_value.as_raw_bytes())?))
|
Ok(LuaValue::String(
|
||||||
|
lua.create_string(raw_value.as_raw_bytes())?,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
None => Ok(Value::Nil),
|
None => Ok(LuaValue::Nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_env_set(_: &Lua, (_, key, value): (Value, String, Option<String>)) -> Result<()> {
|
fn process_env_set(_: &Lua, (_, key, value): (LuaValue, 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(Error::RuntimeError("Key must not be empty".to_string()))
|
Err(LuaError::RuntimeError("Key must not be empty".to_string()))
|
||||||
} else if key.contains('=') {
|
} else if key.contains('=') {
|
||||||
Err(Error::RuntimeError(
|
Err(LuaError::RuntimeError(
|
||||||
"Key must not contain the equals character '='".to_string(),
|
"Key must not contain the equals character '='".to_string(),
|
||||||
))
|
))
|
||||||
} else if key.contains('\0') {
|
} else if key.contains('\0') {
|
||||||
Err(Error::RuntimeError(
|
Err(LuaError::RuntimeError(
|
||||||
"Key must not contain the NUL character".to_string(),
|
"Key must not contain the NUL character".to_string(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,7 +68,7 @@ fn process_env_set(_: &Lua, (_, key, value): (Value, String, Option<String>)) ->
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
// Make sure value is valid, otherwise set_var will panic
|
// Make sure value is valid, otherwise set_var will panic
|
||||||
if value.contains('\0') {
|
if value.contains('\0') {
|
||||||
Err(Error::RuntimeError(
|
Err(LuaError::RuntimeError(
|
||||||
"Value must not contain the NUL character".to_string(),
|
"Value must not contain the NUL character".to_string(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,22 +84,25 @@ fn process_env_set(_: &Lua, (_, key, value): (Value, String, Option<String>)) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_env_iter<'lua>(lua: &'lua Lua, (_, _): (Value<'lua>, ())) -> Result<Function<'lua>> {
|
fn process_env_iter<'lua>(
|
||||||
|
lua: &'lua Lua,
|
||||||
|
(_, _): (LuaValue<'lua>, ()),
|
||||||
|
) -> LuaResult<LuaFunction<'lua>> {
|
||||||
let mut vars = env::vars_os();
|
let mut vars = env::vars_os();
|
||||||
lua.create_function_mut(move |lua, _: ()| match vars.next() {
|
lua.create_function_mut(move |lua, _: ()| match vars.next() {
|
||||||
Some((key, value)) => {
|
Some((key, value)) => {
|
||||||
let raw_key = RawOsString::new(key);
|
let raw_key = RawOsString::new(key);
|
||||||
let raw_value = RawOsString::new(value);
|
let raw_value = RawOsString::new(value);
|
||||||
Ok((
|
Ok((
|
||||||
Value::String(lua.create_string(raw_key.as_raw_bytes())?),
|
LuaValue::String(lua.create_string(raw_key.as_raw_bytes())?),
|
||||||
Value::String(lua.create_string(raw_value.as_raw_bytes())?),
|
LuaValue::String(lua.create_string(raw_value.as_raw_bytes())?),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
None => Ok((Value::Nil, Value::Nil)),
|
None => Ok((LuaValue::Nil, LuaValue::Nil)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_exit(_: &Lua, exit_code: Option<i32>) -> Result<()> {
|
fn process_exit(_: &Lua, exit_code: Option<i32>) -> LuaResult<()> {
|
||||||
// TODO: Exit gracefully to the root with an Ok
|
// TODO: Exit gracefully to the root with an Ok
|
||||||
// result instead of completely exiting the process
|
// result instead of completely exiting the process
|
||||||
if let Some(code) = exit_code {
|
if let Some(code) = exit_code {
|
||||||
|
@ -104,7 +112,10 @@ fn process_exit(_: &Lua, exit_code: Option<i32>) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_spawn(lua: &Lua, (program, args): (String, Option<Vec<String>>)) -> Result<Table> {
|
async fn process_spawn(
|
||||||
|
lua: &Lua,
|
||||||
|
(program, args): (String, Option<Vec<String>>),
|
||||||
|
) -> LuaResult<LuaTable> {
|
||||||
// Create and spawn a child process, and
|
// Create and spawn a child process, and
|
||||||
// wait for it to terminate with output
|
// wait for it to terminate with output
|
||||||
let mut cmd = Command::new(program);
|
let mut cmd = Command::new(program);
|
||||||
|
@ -112,13 +123,13 @@ async fn process_spawn(lua: &Lua, (program, args): (String, Option<Vec<String>>)
|
||||||
cmd.args(args);
|
cmd.args(args);
|
||||||
}
|
}
|
||||||
let child = cmd
|
let child = cmd
|
||||||
.current_dir(env::current_dir().map_err(mlua::Error::external)?)
|
.current_dir(env::current_dir().map_err(LuaError::external)?)
|
||||||
.stdin(Stdio::null())
|
.stdin(Stdio::null())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(mlua::Error::external)?;
|
.map_err(LuaError::external)?;
|
||||||
let output = child.output().await.map_err(mlua::Error::external)?;
|
let output = child.output().await.map_err(LuaError::external)?;
|
||||||
// NOTE: If an exit code was not given by the child process,
|
// NOTE: If an exit code was not given by the child process,
|
||||||
// we default to 1 if it yielded any error output, otherwise 0
|
// we default to 1 if it yielded any error output, otherwise 0
|
||||||
let code = output
|
let code = output
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use mlua::{Error, Function, Lua, Result, Table, Thread, Value, Variadic};
|
use mlua::prelude::*;
|
||||||
use smol::Timer;
|
use smol::Timer;
|
||||||
|
|
||||||
use crate::utils::table_builder::TableBuilder;
|
use crate::utils::table_builder::TableBuilder;
|
||||||
|
|
||||||
type Vararg<'lua> = Variadic<Value<'lua>>;
|
pub async fn create(lua: &Lua) -> LuaResult<()> {
|
||||||
|
|
||||||
pub async fn create(lua: &Lua) -> Result<()> {
|
|
||||||
lua.globals().raw_set(
|
lua.globals().raw_set(
|
||||||
"task",
|
"task",
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
|
@ -20,20 +18,20 @@ pub async fn create(lua: &Lua) -> Result<()> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_create_thread_from_arg<'a>(lua: &'a Lua, arg: Value<'a>) -> Result<Thread<'a>> {
|
fn get_or_create_thread_from_arg<'a>(lua: &'a Lua, arg: LuaValue<'a>) -> LuaResult<LuaThread<'a>> {
|
||||||
match arg {
|
match arg {
|
||||||
Value::Thread(thread) => Ok(thread),
|
LuaValue::Thread(thread) => Ok(thread),
|
||||||
Value::Function(func) => Ok(lua.create_thread(func)?),
|
LuaValue::Function(func) => Ok(lua.create_thread(func)?),
|
||||||
val => Err(Error::RuntimeError(format!(
|
val => Err(LuaError::RuntimeError(format!(
|
||||||
"Expected type thread or function, got {}",
|
"Expected type thread or function, got {}",
|
||||||
val.type_name()
|
val.type_name()
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn resume_thread(lua: &Lua, thread: Thread<'_>, args: Vararg<'_>) -> Result<()> {
|
async fn resume_thread(lua: &Lua, thread: LuaThread<'_>, args: LuaMultiValue<'_>) -> LuaResult<()> {
|
||||||
let coroutine: Table = lua.globals().raw_get("coroutine")?;
|
let coroutine: LuaTable = lua.globals().raw_get("coroutine")?;
|
||||||
let resume: Function = coroutine.raw_get("resume")?;
|
let resume: LuaFunction = coroutine.raw_get("resume")?;
|
||||||
// FIXME: This is blocking, we should spawn a local tokio task,
|
// FIXME: This is blocking, we should spawn a local tokio task,
|
||||||
// but doing that moves "thread" and "args", that both have
|
// but doing that moves "thread" and "args", that both have
|
||||||
// the lifetime of the outer function, so it doesn't work
|
// the lifetime of the outer function, so it doesn't work
|
||||||
|
@ -41,14 +39,17 @@ async fn resume_thread(lua: &Lua, thread: Thread<'_>, args: Vararg<'_>) -> Resul
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn task_cancel(lua: &Lua, thread: Thread<'_>) -> Result<()> {
|
async fn task_cancel(lua: &Lua, thread: LuaThread<'_>) -> LuaResult<()> {
|
||||||
let coroutine: Table = lua.globals().raw_get("coroutine")?;
|
let coroutine: LuaTable = lua.globals().raw_get("coroutine")?;
|
||||||
let close: Function = coroutine.raw_get("close")?;
|
let close: LuaFunction = coroutine.raw_get("close")?;
|
||||||
close.call_async(thread).await?;
|
close.call_async(thread).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn task_defer<'a>(lua: &'a Lua, (tof, args): (Value<'a>, Vararg<'a>)) -> Result<Thread<'a>> {
|
async fn task_defer<'a>(
|
||||||
|
lua: &'a Lua,
|
||||||
|
(tof, args): (LuaValue<'a>, LuaMultiValue<'a>),
|
||||||
|
) -> LuaResult<LuaThread<'a>> {
|
||||||
// TODO: Defer (sleep a minimum amount of time)
|
// TODO: Defer (sleep a minimum amount of time)
|
||||||
let thread = get_or_create_thread_from_arg(lua, tof)?;
|
let thread = get_or_create_thread_from_arg(lua, tof)?;
|
||||||
resume_thread(lua, thread.clone(), args).await?;
|
resume_thread(lua, thread.clone(), args).await?;
|
||||||
|
@ -57,15 +58,18 @@ async fn task_defer<'a>(lua: &'a Lua, (tof, args): (Value<'a>, Vararg<'a>)) -> R
|
||||||
|
|
||||||
async fn task_delay<'a>(
|
async fn task_delay<'a>(
|
||||||
lua: &'a Lua,
|
lua: &'a Lua,
|
||||||
(_delay, tof, args): (Option<f32>, Value<'a>, Vararg<'a>),
|
(_delay, tof, args): (Option<f32>, LuaValue<'a>, LuaMultiValue<'a>),
|
||||||
) -> Result<Thread<'a>> {
|
) -> LuaResult<LuaThread<'a>> {
|
||||||
// TODO: Delay by the amount of time wanted
|
// TODO: Delay by the amount of time wanted
|
||||||
let thread = get_or_create_thread_from_arg(lua, tof)?;
|
let thread = get_or_create_thread_from_arg(lua, tof)?;
|
||||||
resume_thread(lua, thread.clone(), args).await?;
|
resume_thread(lua, thread.clone(), args).await?;
|
||||||
Ok(thread)
|
Ok(thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn task_spawn<'a>(lua: &'a Lua, (tof, args): (Value<'a>, Vararg<'a>)) -> Result<Thread<'a>> {
|
async fn task_spawn<'a>(
|
||||||
|
lua: &'a Lua,
|
||||||
|
(tof, args): (LuaValue<'a>, LuaMultiValue<'a>),
|
||||||
|
) -> LuaResult<LuaThread<'a>> {
|
||||||
let thread = get_or_create_thread_from_arg(lua, tof)?;
|
let thread = get_or_create_thread_from_arg(lua, tof)?;
|
||||||
resume_thread(lua, thread.clone(), args).await?;
|
resume_thread(lua, thread.clone(), args).await?;
|
||||||
Ok(thread)
|
Ok(thread)
|
||||||
|
@ -74,7 +78,7 @@ async fn task_spawn<'a>(lua: &'a Lua, (tof, args): (Value<'a>, Vararg<'a>)) -> R
|
||||||
// FIXME: It doesn't seem possible to properly make an async wait
|
// FIXME: It doesn't seem possible to properly make an async wait
|
||||||
// function with mlua right now, something breaks when using
|
// function with mlua right now, something breaks when using
|
||||||
// the async wait function inside of a coroutine
|
// the async wait function inside of a coroutine
|
||||||
async fn task_wait(_: &Lua, duration: Option<f32>) -> Result<f32> {
|
async fn task_wait(_: &Lua, duration: Option<f32>) -> LuaResult<f32> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
Timer::after(
|
Timer::after(
|
||||||
duration
|
duration
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::{
|
||||||
io::{self, Write as _},
|
io::{self, Write as _},
|
||||||
};
|
};
|
||||||
|
|
||||||
use mlua::{MultiValue, Value};
|
use mlua::prelude::*;
|
||||||
|
|
||||||
const MAX_FORMAT_DEPTH: usize = 4;
|
const MAX_FORMAT_DEPTH: usize = 4;
|
||||||
|
|
||||||
|
@ -25,11 +25,11 @@ pub const STYLE_RESET: &str = if cfg!(test) { "" } else { "\x1B[22m" };
|
||||||
pub const STYLE_BOLD: &str = if cfg!(test) { "" } else { "\x1B[1m" };
|
pub const STYLE_BOLD: &str = if cfg!(test) { "" } else { "\x1B[1m" };
|
||||||
pub const STYLE_DIM: &str = if cfg!(test) { "" } else { "\x1B[2m" };
|
pub const STYLE_DIM: &str = if cfg!(test) { "" } else { "\x1B[2m" };
|
||||||
|
|
||||||
pub fn flush_stdout() -> mlua::Result<()> {
|
pub fn flush_stdout() -> LuaResult<()> {
|
||||||
io::stdout().flush().map_err(mlua::Error::external)
|
io::stdout().flush().map_err(LuaError::external)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_be_plain_lua_table_key(s: &mlua::String) -> bool {
|
fn can_be_plain_lua_table_key(s: &LuaString) -> bool {
|
||||||
let str = s.to_string_lossy().to_string();
|
let str = s.to_string_lossy().to_string();
|
||||||
let first_char = str.chars().next().unwrap();
|
let first_char = str.chars().next().unwrap();
|
||||||
if first_char.is_alphabetic() {
|
if first_char.is_alphabetic() {
|
||||||
|
@ -56,13 +56,13 @@ pub fn format_label<S: AsRef<str>>(s: S) -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_label<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
pub fn print_label<S: AsRef<str>>(s: S) -> LuaResult<()> {
|
||||||
print!("{}", format_label(s));
|
print!("{}", format_label(s));
|
||||||
flush_stdout()?;
|
flush_stdout()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_style<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
pub fn print_style<S: AsRef<str>>(s: S) -> LuaResult<()> {
|
||||||
print!(
|
print!(
|
||||||
"{}",
|
"{}",
|
||||||
match s.as_ref() {
|
match s.as_ref() {
|
||||||
|
@ -70,7 +70,7 @@ pub fn print_style<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||||
"bold" => STYLE_BOLD,
|
"bold" => STYLE_BOLD,
|
||||||
"dim" => STYLE_DIM,
|
"dim" => STYLE_DIM,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(mlua::Error::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"The style '{}' is not a valid style name",
|
"The style '{}' is not a valid style name",
|
||||||
s.as_ref()
|
s.as_ref()
|
||||||
)));
|
)));
|
||||||
|
@ -81,7 +81,7 @@ pub fn print_style<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_color<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
pub fn print_color<S: AsRef<str>>(s: S) -> LuaResult<()> {
|
||||||
print!(
|
print!(
|
||||||
"{}",
|
"{}",
|
||||||
match s.as_ref() {
|
match s.as_ref() {
|
||||||
|
@ -95,7 +95,7 @@ pub fn print_color<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||||
"cyan" => COLOR_CYAN,
|
"cyan" => COLOR_CYAN,
|
||||||
"white" => COLOR_WHITE,
|
"white" => COLOR_WHITE,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(mlua::Error::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"The color '{}' is not a valid color name",
|
"The color '{}' is not a valid color name",
|
||||||
s.as_ref()
|
s.as_ref()
|
||||||
)));
|
)));
|
||||||
|
@ -106,16 +106,20 @@ pub fn print_color<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_format_value(buffer: &mut String, value: &Value, depth: usize) -> anyhow::Result<()> {
|
pub fn pretty_format_value(
|
||||||
|
buffer: &mut String,
|
||||||
|
value: &LuaValue,
|
||||||
|
depth: usize,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
// TODO: Handle tables with cyclic references
|
// TODO: Handle tables with cyclic references
|
||||||
// TODO: Handle other types like function, userdata, ...
|
// TODO: Handle other types like function, userdata, ...
|
||||||
match &value {
|
match &value {
|
||||||
Value::Nil => write!(buffer, "nil")?,
|
LuaValue::Nil => write!(buffer, "nil")?,
|
||||||
Value::Boolean(true) => write!(buffer, "{COLOR_YELLOW}true{COLOR_RESET}")?,
|
LuaValue::Boolean(true) => write!(buffer, "{COLOR_YELLOW}true{COLOR_RESET}")?,
|
||||||
Value::Boolean(false) => write!(buffer, "{COLOR_YELLOW}false{COLOR_RESET}")?,
|
LuaValue::Boolean(false) => write!(buffer, "{COLOR_YELLOW}false{COLOR_RESET}")?,
|
||||||
Value::Number(n) => write!(buffer, "{COLOR_CYAN}{n}{COLOR_RESET}")?,
|
LuaValue::Number(n) => write!(buffer, "{COLOR_CYAN}{n}{COLOR_RESET}")?,
|
||||||
Value::Integer(i) => write!(buffer, "{COLOR_CYAN}{i}{COLOR_RESET}")?,
|
LuaValue::Integer(i) => write!(buffer, "{COLOR_CYAN}{i}{COLOR_RESET}")?,
|
||||||
Value::String(s) => write!(
|
LuaValue::String(s) => write!(
|
||||||
buffer,
|
buffer,
|
||||||
"{}\"{}\"{}",
|
"{}\"{}\"{}",
|
||||||
COLOR_GREEN,
|
COLOR_GREEN,
|
||||||
|
@ -124,17 +128,17 @@ pub fn pretty_format_value(buffer: &mut String, value: &Value, depth: usize) ->
|
||||||
.replace('\n', r#"\n"#),
|
.replace('\n', r#"\n"#),
|
||||||
COLOR_RESET
|
COLOR_RESET
|
||||||
)?,
|
)?,
|
||||||
Value::Table(ref tab) => {
|
LuaValue::Table(ref tab) => {
|
||||||
if depth >= MAX_FORMAT_DEPTH {
|
if depth >= MAX_FORMAT_DEPTH {
|
||||||
write!(buffer, "{STYLE_DIM}{{ ... }}{STYLE_RESET}")?;
|
write!(buffer, "{STYLE_DIM}{{ ... }}{STYLE_RESET}")?;
|
||||||
} else {
|
} else {
|
||||||
let mut is_empty = false;
|
let mut is_empty = false;
|
||||||
let depth_indent = INDENT.repeat(depth);
|
let depth_indent = INDENT.repeat(depth);
|
||||||
write!(buffer, "{STYLE_DIM}{{{STYLE_RESET}")?;
|
write!(buffer, "{STYLE_DIM}{{{STYLE_RESET}")?;
|
||||||
for pair in tab.clone().pairs::<Value, Value>() {
|
for pair in tab.clone().pairs::<LuaValue, LuaValue>() {
|
||||||
let (key, value) = pair?;
|
let (key, value) = pair?;
|
||||||
match &key {
|
match &key {
|
||||||
Value::String(s) if can_be_plain_lua_table_key(s) => write!(
|
LuaValue::String(s) if can_be_plain_lua_table_key(s) => write!(
|
||||||
buffer,
|
buffer,
|
||||||
"\n{}{}{} {}={} ",
|
"\n{}{}{} {}={} ",
|
||||||
depth_indent,
|
depth_indent,
|
||||||
|
@ -160,12 +164,12 @@ pub fn pretty_format_value(buffer: &mut String, value: &Value, depth: usize) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Vector(x, y, z) => {
|
LuaValue::Vector(x, y, z) => {
|
||||||
write!(buffer, "{COLOR_PURPLE}<vector({x}, {y}, {z})>{COLOR_RESET}",)?
|
write!(buffer, "{COLOR_PURPLE}<vector({x}, {y}, {z})>{COLOR_RESET}",)?
|
||||||
}
|
}
|
||||||
Value::Thread(_) => write!(buffer, "{COLOR_PURPLE}<thread>{COLOR_RESET}")?,
|
LuaValue::Thread(_) => write!(buffer, "{COLOR_PURPLE}<thread>{COLOR_RESET}")?,
|
||||||
Value::Function(_) => write!(buffer, "{COLOR_PURPLE}<function>{COLOR_RESET}")?,
|
LuaValue::Function(_) => write!(buffer, "{COLOR_PURPLE}<function>{COLOR_RESET}")?,
|
||||||
Value::UserData(_) | Value::LightUserData(_) => {
|
LuaValue::UserData(_) | LuaValue::LightUserData(_) => {
|
||||||
write!(buffer, "{COLOR_PURPLE}<userdata>{COLOR_RESET}")?
|
write!(buffer, "{COLOR_PURPLE}<userdata>{COLOR_RESET}")?
|
||||||
}
|
}
|
||||||
_ => write!(buffer, "?")?,
|
_ => write!(buffer, "?")?,
|
||||||
|
@ -173,28 +177,28 @@ pub fn pretty_format_value(buffer: &mut String, value: &Value, depth: usize) ->
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_format_multi_value(multi: &MultiValue) -> mlua::Result<String> {
|
pub fn pretty_format_multi_value(multi: &LuaMultiValue) -> LuaResult<String> {
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
for value in multi {
|
for value in multi {
|
||||||
counter += 1;
|
counter += 1;
|
||||||
if let Value::String(s) = value {
|
if let LuaValue::String(s) = value {
|
||||||
write!(buffer, "{}", s.to_string_lossy()).map_err(mlua::Error::external)?;
|
write!(buffer, "{}", s.to_string_lossy()).map_err(LuaError::external)?;
|
||||||
} else {
|
} else {
|
||||||
pretty_format_value(&mut buffer, value, 0).map_err(mlua::Error::external)?;
|
pretty_format_value(&mut buffer, value, 0).map_err(LuaError::external)?;
|
||||||
}
|
}
|
||||||
if counter < multi.len() {
|
if counter < multi.len() {
|
||||||
write!(&mut buffer, " ").map_err(mlua::Error::external)?;
|
write!(&mut buffer, " ").map_err(LuaError::external)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_format_luau_error(e: &mlua::Error) -> String {
|
pub fn pretty_format_luau_error(e: &LuaError) -> String {
|
||||||
let stack_begin = format!("[{}Stack Begin{}]", COLOR_BLUE, COLOR_RESET);
|
let stack_begin = format!("[{}Stack Begin{}]", COLOR_BLUE, COLOR_RESET);
|
||||||
let stack_end = format!("[{}Stack End{}]", COLOR_BLUE, COLOR_RESET);
|
let stack_end = format!("[{}Stack End{}]", COLOR_BLUE, COLOR_RESET);
|
||||||
let err_string = match e {
|
let err_string = match e {
|
||||||
mlua::Error::RuntimeError(e) => {
|
LuaError::RuntimeError(e) => {
|
||||||
// Add "Stack Begin" instead of default stack traceback string
|
// Add "Stack Begin" instead of default stack traceback string
|
||||||
let err_string = e.to_string();
|
let err_string = e.to_string();
|
||||||
let mut err_lines = err_string
|
let mut err_lines = err_string
|
||||||
|
@ -211,7 +215,7 @@ pub fn pretty_format_luau_error(e: &mlua::Error) -> String {
|
||||||
err_lines.push(stack_end);
|
err_lines.push(stack_end);
|
||||||
err_lines.join("\n")
|
err_lines.join("\n")
|
||||||
}
|
}
|
||||||
mlua::Error::CallbackError { cause, traceback } => {
|
LuaError::CallbackError { cause, traceback } => {
|
||||||
// Same error formatting as above
|
// Same error formatting as above
|
||||||
format!(
|
format!(
|
||||||
"{}\n{}{}{}",
|
"{}\n{}{}{}",
|
||||||
|
@ -221,7 +225,7 @@ pub fn pretty_format_luau_error(e: &mlua::Error) -> String {
|
||||||
stack_end
|
stack_end
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
mlua::Error::ToLuaConversionError { from, to, message } => {
|
LuaError::ToLuaConversionError { from, to, message } => {
|
||||||
let msg = message
|
let msg = message
|
||||||
.clone()
|
.clone()
|
||||||
.map_or_else(String::new, |m| format!("\nDetails:\n\t{m}"));
|
.map_or_else(String::new, |m| format!("\nDetails:\n\t{m}"));
|
||||||
|
@ -230,7 +234,7 @@ pub fn pretty_format_luau_error(e: &mlua::Error) -> String {
|
||||||
from, to, msg
|
from, to, msg
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
mlua::Error::FromLuaConversionError { from, to, message } => {
|
LuaError::FromLuaConversionError { from, to, message } => {
|
||||||
let msg = message
|
let msg = message
|
||||||
.clone()
|
.clone()
|
||||||
.map_or_else(String::new, |m| format!("\nDetails:\n\t{m}"));
|
.map_or_else(String::new, |m| format!("\nDetails:\n\t{m}"));
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
use mlua::{FromLuaMulti, Lua, Result, Table, ToLua, ToLuaMulti, Value};
|
use mlua::prelude::*;
|
||||||
|
|
||||||
pub struct TableBuilder<'lua> {
|
pub struct TableBuilder<'lua> {
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
tab: Table<'lua>,
|
tab: LuaTable<'lua>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> TableBuilder<'lua> {
|
impl<'lua> TableBuilder<'lua> {
|
||||||
pub fn new(lua: &'lua Lua) -> Result<Self> {
|
pub fn new(lua: &'lua Lua) -> LuaResult<Self> {
|
||||||
let tab = lua.create_table()?;
|
let tab = lua.create_table()?;
|
||||||
Ok(Self { lua, tab })
|
Ok(Self { lua, tab })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_value<K, V>(self, key: K, value: V) -> Result<Self>
|
pub fn with_value<K, V>(self, key: K, value: V) -> LuaResult<Self>
|
||||||
where
|
where
|
||||||
K: ToLua<'lua>,
|
K: ToLua<'lua>,
|
||||||
V: ToLua<'lua>,
|
V: ToLua<'lua>,
|
||||||
|
@ -22,7 +22,7 @@ impl<'lua> TableBuilder<'lua> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_values<K, V>(self, values: Vec<(K, V)>) -> Result<Self>
|
pub fn with_values<K, V>(self, values: Vec<(K, V)>) -> LuaResult<Self>
|
||||||
where
|
where
|
||||||
K: ToLua<'lua>,
|
K: ToLua<'lua>,
|
||||||
V: ToLua<'lua>,
|
V: ToLua<'lua>,
|
||||||
|
@ -33,7 +33,7 @@ impl<'lua> TableBuilder<'lua> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_sequential_value<V>(self, value: V) -> Result<Self>
|
pub fn with_sequential_value<V>(self, value: V) -> LuaResult<Self>
|
||||||
where
|
where
|
||||||
V: ToLua<'lua>,
|
V: ToLua<'lua>,
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@ impl<'lua> TableBuilder<'lua> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_sequential_values<V>(self, values: Vec<V>) -> Result<Self>
|
pub fn with_sequential_values<V>(self, values: Vec<V>) -> LuaResult<Self>
|
||||||
where
|
where
|
||||||
V: ToLua<'lua>,
|
V: ToLua<'lua>,
|
||||||
{
|
{
|
||||||
|
@ -51,40 +51,40 @@ impl<'lua> TableBuilder<'lua> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_metatable(self, table: Table) -> Result<Self> {
|
pub fn with_metatable(self, table: LuaTable) -> LuaResult<Self> {
|
||||||
self.tab.set_metatable(Some(table));
|
self.tab.set_metatable(Some(table));
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_function<K, A, R, F>(self, key: K, func: F) -> Result<Self>
|
pub fn with_function<K, A, R, F>(self, key: K, func: F) -> LuaResult<Self>
|
||||||
where
|
where
|
||||||
K: ToLua<'lua>,
|
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) -> LuaResult<R>,
|
||||||
{
|
{
|
||||||
let f = self.lua.create_function(func)?;
|
let f = self.lua.create_function(func)?;
|
||||||
self.with_value(key, Value::Function(f))
|
self.with_value(key, LuaValue::Function(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_async_function<K, A, R, F, FR>(self, key: K, func: F) -> Result<Self>
|
pub fn with_async_function<K, A, R, F, FR>(self, key: K, func: F) -> LuaResult<Self>
|
||||||
where
|
where
|
||||||
K: ToLua<'lua>,
|
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,
|
||||||
FR: 'lua + Future<Output = Result<R>>,
|
FR: 'lua + Future<Output = LuaResult<R>>,
|
||||||
{
|
{
|
||||||
let f = self.lua.create_async_function(func)?;
|
let f = self.lua.create_async_function(func)?;
|
||||||
self.with_value(key, Value::Function(f))
|
self.with_value(key, LuaValue::Function(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_readonly(self) -> Result<Table<'lua>> {
|
pub fn build_readonly(self) -> LuaResult<LuaTable<'lua>> {
|
||||||
self.tab.set_readonly(true);
|
self.tab.set_readonly(true);
|
||||||
Ok(self.tab)
|
Ok(self.tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Result<Table<'lua>> {
|
pub fn build(self) -> LuaResult<LuaTable<'lua>> {
|
||||||
Ok(self.tab)
|
Ok(self.tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue