mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Prepare for task scheduler, improve error formatting
This commit is contained in:
parent
7aa35d8130
commit
7814282d3d
5 changed files with 75 additions and 79 deletions
|
@ -3,7 +3,7 @@ use std::fs::read_to_string;
|
|||
use anyhow::Result;
|
||||
use clap::{CommandFactory, Parser};
|
||||
|
||||
use lune::Lune;
|
||||
use lune::run_lune;
|
||||
|
||||
use crate::utils::{files::find_parse_file_path, github::Client as GithubClient};
|
||||
|
||||
|
@ -96,11 +96,7 @@ impl Cli {
|
|||
// Display the file path relative to cwd with no extensions in stack traces
|
||||
let file_display_name = file_path.with_extension("").display().to_string();
|
||||
// Create a new lune object with all globals & run the script
|
||||
Lune::new()?
|
||||
.with_args(self.script_args)?
|
||||
.with_default_globals()?
|
||||
.run_with_name(&file_contents, &file_display_name)
|
||||
.await?;
|
||||
run_lune(&file_display_name, &file_contents, self.script_args).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,3 +9,5 @@ pub use fs::new as new_fs;
|
|||
pub use net::new as new_net;
|
||||
pub use process::new as new_process;
|
||||
pub use task::new as new_task;
|
||||
|
||||
pub use task::WaitingThread as WaitingTaskThread;
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
use std::time::Duration;
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use mlua::{Function, Lua, Result, Table, Value, Variadic};
|
||||
use mlua::{Function, Lua, Result, Table, Thread, Value, Variadic};
|
||||
use tokio::time;
|
||||
|
||||
use crate::utils::table_builder::ReadonlyTableBuilder;
|
||||
|
||||
const DEFAULT_SLEEP_DURATION: f32 = 1.0 / 60.0;
|
||||
|
||||
pub fn new(lua: &Lua) -> Result<Table> {
|
||||
pub struct WaitingThread<'a> {
|
||||
is_delayed_for: Option<f32>,
|
||||
is_deferred: Option<bool>,
|
||||
thread: Thread<'a>,
|
||||
args: Variadic<Value<'a>>,
|
||||
}
|
||||
|
||||
pub fn new<'a>(lua: &'a Lua, threads: &Arc<Mutex<Vec<WaitingThread<'a>>>>) -> Result<Table<'a>> {
|
||||
// TODO: Figure out how to insert into threads vec
|
||||
ReadonlyTableBuilder::new(lua)?
|
||||
.with_async_function(
|
||||
"defer",
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use anyhow::Result;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use mlua::Lua;
|
||||
|
||||
pub mod globals;
|
||||
|
@ -6,63 +8,39 @@ pub mod utils;
|
|||
|
||||
use crate::{
|
||||
globals::{new_console, new_fs, new_net, new_process, new_task},
|
||||
utils::formatting::{pretty_print_luau_error, print_label},
|
||||
utils::formatting::{format_label, pretty_format_luau_error},
|
||||
};
|
||||
|
||||
pub struct Lune {
|
||||
lua: Lua,
|
||||
args: Vec<String>,
|
||||
}
|
||||
|
||||
impl Lune {
|
||||
pub fn new() -> Result<Self> {
|
||||
let lua = Lua::new();
|
||||
lua.sandbox(true)?;
|
||||
Ok(Self { lua, args: vec![] })
|
||||
pub async fn run_lune(name: &str, chunk: &str, args: Vec<String>) -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
let threads = Arc::new(Mutex::new(Vec::new()));
|
||||
lua.sandbox(true)?;
|
||||
// Add in all globals
|
||||
{
|
||||
let globals = lua.globals();
|
||||
globals.raw_set("console", new_console(&lua)?)?;
|
||||
globals.raw_set("fs", new_fs(&lua)?)?;
|
||||
globals.raw_set("net", new_net(&lua)?)?;
|
||||
globals.raw_set("process", new_process(&lua, args.clone())?)?;
|
||||
globals.raw_set("task", new_task(&lua, &threads)?)?;
|
||||
globals.set_readonly(true);
|
||||
}
|
||||
|
||||
pub fn with_args(mut self, args: Vec<String>) -> Result<Self> {
|
||||
self.args = args;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn with_default_globals(self) -> Result<Self> {
|
||||
{
|
||||
let globals = self.lua.globals();
|
||||
globals.raw_set("console", new_console(&self.lua)?)?;
|
||||
globals.raw_set("fs", new_fs(&self.lua)?)?;
|
||||
globals.raw_set("net", new_net(&self.lua)?)?;
|
||||
globals.raw_set("process", new_process(&self.lua, self.args.clone())?)?;
|
||||
globals.raw_set("task", new_task(&self.lua)?)?;
|
||||
globals.set_readonly(true);
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub async fn run(&self, chunk: &str) -> Result<()> {
|
||||
self.handle_result(self.lua.load(chunk).exec_async().await)
|
||||
}
|
||||
|
||||
pub async fn run_with_name(&self, chunk: &str, name: &str) -> Result<()> {
|
||||
self.handle_result(self.lua.load(chunk).set_name(name)?.exec_async().await)
|
||||
}
|
||||
|
||||
fn handle_result(&self, result: mlua::Result<()>) -> Result<()> {
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
eprintln!();
|
||||
print_label("ERROR").unwrap();
|
||||
eprintln!();
|
||||
pretty_print_luau_error(&e);
|
||||
Err(e.into())
|
||||
}
|
||||
}
|
||||
// Run the requested chunk asynchronously
|
||||
let result = lua.load(chunk).set_name(name)?.exec_async().await;
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => bail!(
|
||||
"\n{}\n{}",
|
||||
format_label("ERROR"),
|
||||
pretty_format_luau_error(&e)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::run_lune;
|
||||
|
||||
macro_rules! run_tests {
|
||||
($($name:ident: $value:expr,)*) => {
|
||||
$(
|
||||
|
@ -75,16 +53,10 @@ mod tests {
|
|||
let path = std::env::current_dir()
|
||||
.unwrap()
|
||||
.join(format!("src/tests/{}.luau", $value));
|
||||
let lune = crate::Lune::new()
|
||||
.unwrap()
|
||||
.with_args(args)
|
||||
.unwrap()
|
||||
.with_default_globals()
|
||||
.unwrap();
|
||||
let script = tokio::fs::read_to_string(&path)
|
||||
.await
|
||||
.unwrap();
|
||||
if let Err(e) = lune.run_with_name(&script, $value).await {
|
||||
if let Err(e) = run_lune($value, &script, args).await {
|
||||
panic!("Test '{}' failed!\n{}", $value, e.to_string())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ fn can_be_plain_lua_table_key(s: &mlua::String) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn print_label<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||
print!(
|
||||
pub fn format_label<S: AsRef<str>>(s: S) -> String {
|
||||
format!(
|
||||
"{}[{}{}{}{}]{} ",
|
||||
STYLE_BOLD,
|
||||
match s.as_ref().to_ascii_lowercase().as_str() {
|
||||
|
@ -53,7 +53,11 @@ pub fn print_label<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
|||
COLOR_RESET,
|
||||
STYLE_BOLD,
|
||||
STYLE_RESET
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
pub fn print_label<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||
print!("{}", format_label(s));
|
||||
flush_stdout()?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -186,34 +190,45 @@ pub fn pretty_format_multi_value(multi: &MultiValue) -> mlua::Result<String> {
|
|||
Ok(buffer)
|
||||
}
|
||||
|
||||
pub fn pretty_print_luau_error(e: &mlua::Error) {
|
||||
pub fn pretty_format_luau_error(e: &mlua::Error) -> String {
|
||||
match e {
|
||||
mlua::Error::RuntimeError(e) => {
|
||||
eprintln!("{e}");
|
||||
let err_string = e.to_string();
|
||||
let mut err_lines = err_string.lines().collect::<Vec<_>>();
|
||||
for (index, line) in err_lines.clone().iter().enumerate().rev() {
|
||||
if *line == "stack traceback:" {
|
||||
err_lines[index] = "Stack Begin";
|
||||
break;
|
||||
}
|
||||
}
|
||||
err_lines.push("Stack End");
|
||||
err_lines.join("\n")
|
||||
}
|
||||
mlua::Error::CallbackError { cause, traceback } => {
|
||||
pretty_print_luau_error(cause.as_ref());
|
||||
eprintln!("Traceback:");
|
||||
eprintln!("{}", traceback.strip_prefix("stack traceback:\n").unwrap());
|
||||
format!(
|
||||
"{}\nStack Begin{}Stack End",
|
||||
pretty_format_luau_error(cause.as_ref()),
|
||||
traceback.strip_prefix("stack traceback:\n").unwrap()
|
||||
)
|
||||
}
|
||||
mlua::Error::ToLuaConversionError { from, to, message } => {
|
||||
let msg = message
|
||||
.clone()
|
||||
.map_or_else(String::new, |m| format!("\nDetails:\n\t{m}"));
|
||||
eprintln!(
|
||||
format!(
|
||||
"Failed to convert Rust type '{}' into Luau type '{}'!{}",
|
||||
from, to, msg
|
||||
);
|
||||
)
|
||||
}
|
||||
mlua::Error::FromLuaConversionError { from, to, message } => {
|
||||
let msg = message
|
||||
.clone()
|
||||
.map_or_else(String::new, |m| format!("\nDetails:\n\t{m}"));
|
||||
eprintln!(
|
||||
format!(
|
||||
"Failed to convert Luau type '{}' into Rust type '{}'!{}",
|
||||
from, to, msg
|
||||
);
|
||||
)
|
||||
}
|
||||
e => eprintln!("{e}"),
|
||||
e => format!("{e}"),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue