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 anyhow::Result;
|
||||||
use clap::{CommandFactory, Parser};
|
use clap::{CommandFactory, Parser};
|
||||||
|
|
||||||
use lune::Lune;
|
use lune::run_lune;
|
||||||
|
|
||||||
use crate::utils::{files::find_parse_file_path, github::Client as GithubClient};
|
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
|
// Display the file path relative to cwd with no extensions in stack traces
|
||||||
let file_display_name = file_path.with_extension("").display().to_string();
|
let file_display_name = file_path.with_extension("").display().to_string();
|
||||||
// Create a new lune object with all globals & run the script
|
// Create a new lune object with all globals & run the script
|
||||||
Lune::new()?
|
run_lune(&file_display_name, &file_contents, self.script_args).await?;
|
||||||
.with_args(self.script_args)?
|
|
||||||
.with_default_globals()?
|
|
||||||
.run_with_name(&file_contents, &file_display_name)
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,3 +9,5 @@ pub use fs::new as new_fs;
|
||||||
pub use net::new as new_net;
|
pub use net::new as new_net;
|
||||||
pub use process::new as new_process;
|
pub use process::new as new_process;
|
||||||
pub use task::new as new_task;
|
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 tokio::time;
|
||||||
|
|
||||||
use crate::utils::table_builder::ReadonlyTableBuilder;
|
use crate::utils::table_builder::ReadonlyTableBuilder;
|
||||||
|
|
||||||
const DEFAULT_SLEEP_DURATION: f32 = 1.0 / 60.0;
|
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)?
|
ReadonlyTableBuilder::new(lua)?
|
||||||
.with_async_function(
|
.with_async_function(
|
||||||
"defer",
|
"defer",
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use anyhow::Result;
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use anyhow::{bail, Result};
|
||||||
use mlua::Lua;
|
use mlua::Lua;
|
||||||
|
|
||||||
pub mod globals;
|
pub mod globals;
|
||||||
|
@ -6,63 +8,39 @@ pub mod utils;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
globals::{new_console, new_fs, new_net, new_process, new_task},
|
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 {
|
pub async fn run_lune(name: &str, chunk: &str, args: Vec<String>) -> Result<()> {
|
||||||
lua: Lua,
|
let lua = Lua::new();
|
||||||
args: Vec<String>,
|
let threads = Arc::new(Mutex::new(Vec::new()));
|
||||||
}
|
lua.sandbox(true)?;
|
||||||
|
// Add in all globals
|
||||||
impl Lune {
|
{
|
||||||
pub fn new() -> Result<Self> {
|
let globals = lua.globals();
|
||||||
let lua = Lua::new();
|
globals.raw_set("console", new_console(&lua)?)?;
|
||||||
lua.sandbox(true)?;
|
globals.raw_set("fs", new_fs(&lua)?)?;
|
||||||
Ok(Self { lua, args: vec![] })
|
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);
|
||||||
}
|
}
|
||||||
|
// Run the requested chunk asynchronously
|
||||||
pub fn with_args(mut self, args: Vec<String>) -> Result<Self> {
|
let result = lua.load(chunk).set_name(name)?.exec_async().await;
|
||||||
self.args = args;
|
match result {
|
||||||
Ok(self)
|
Ok(_) => Ok(()),
|
||||||
}
|
Err(e) => bail!(
|
||||||
|
"\n{}\n{}",
|
||||||
pub fn with_default_globals(self) -> Result<Self> {
|
format_label("ERROR"),
|
||||||
{
|
pretty_format_luau_error(&e)
|
||||||
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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::run_lune;
|
||||||
|
|
||||||
macro_rules! run_tests {
|
macro_rules! run_tests {
|
||||||
($($name:ident: $value:expr,)*) => {
|
($($name:ident: $value:expr,)*) => {
|
||||||
$(
|
$(
|
||||||
|
@ -75,16 +53,10 @@ mod tests {
|
||||||
let path = std::env::current_dir()
|
let path = std::env::current_dir()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.join(format!("src/tests/{}.luau", $value));
|
.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)
|
let script = tokio::fs::read_to_string(&path)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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())
|
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<()> {
|
pub fn format_label<S: AsRef<str>>(s: S) -> String {
|
||||||
print!(
|
format!(
|
||||||
"{}[{}{}{}{}]{} ",
|
"{}[{}{}{}{}]{} ",
|
||||||
STYLE_BOLD,
|
STYLE_BOLD,
|
||||||
match s.as_ref().to_ascii_lowercase().as_str() {
|
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,
|
COLOR_RESET,
|
||||||
STYLE_BOLD,
|
STYLE_BOLD,
|
||||||
STYLE_RESET
|
STYLE_RESET
|
||||||
);
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_label<S: AsRef<str>>(s: S) -> mlua::Result<()> {
|
||||||
|
print!("{}", format_label(s));
|
||||||
flush_stdout()?;
|
flush_stdout()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -186,34 +190,45 @@ pub fn pretty_format_multi_value(multi: &MultiValue) -> mlua::Result<String> {
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_print_luau_error(e: &mlua::Error) {
|
pub fn pretty_format_luau_error(e: &mlua::Error) -> String {
|
||||||
match e {
|
match e {
|
||||||
mlua::Error::RuntimeError(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 } => {
|
mlua::Error::CallbackError { cause, traceback } => {
|
||||||
pretty_print_luau_error(cause.as_ref());
|
format!(
|
||||||
eprintln!("Traceback:");
|
"{}\nStack Begin{}Stack End",
|
||||||
eprintln!("{}", traceback.strip_prefix("stack traceback:\n").unwrap());
|
pretty_format_luau_error(cause.as_ref()),
|
||||||
|
traceback.strip_prefix("stack traceback:\n").unwrap()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
mlua::Error::ToLuaConversionError { from, to, message } => {
|
mlua::Error::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}"));
|
||||||
eprintln!(
|
format!(
|
||||||
"Failed to convert Rust type '{}' into Luau type '{}'!{}",
|
"Failed to convert Rust type '{}' into Luau type '{}'!{}",
|
||||||
from, to, msg
|
from, to, msg
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
mlua::Error::FromLuaConversionError { from, to, message } => {
|
mlua::Error::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}"));
|
||||||
eprintln!(
|
format!(
|
||||||
"Failed to convert Luau type '{}' into Rust type '{}'!{}",
|
"Failed to convert Luau type '{}' into Rust type '{}'!{}",
|
||||||
from, to, msg
|
from, to, msg
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
e => eprintln!("{e}"),
|
e => format!("{e}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue