From 4ce2d3a80f733c7eabe5efba8ff888fa8e846cbc Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Thu, 24 Apr 2025 21:15:46 +0200 Subject: [PATCH] Make runtime return values into a non exhaustive struct to prevent future breakage --- crates/lune/src/cli/run.rs | 2 +- crates/lune/src/lib.rs | 2 +- crates/lune/src/rt/mod.rs | 2 +- crates/lune/src/rt/runtime.rs | 55 ++++++++++++++++++++++++++----- crates/lune/src/standalone/mod.rs | 2 +- crates/lune/src/tests.rs | 4 +-- 6 files changed, 53 insertions(+), 14 deletions(-) diff --git a/crates/lune/src/cli/run.rs b/crates/lune/src/cli/run.rs index 65df5ed..f86f324 100644 --- a/crates/lune/src/cli/run.rs +++ b/crates/lune/src/cli/run.rs @@ -57,7 +57,7 @@ impl RunCommand { eprintln!("{err}"); ExitCode::FAILURE } - Ok((code, _)) => ExitCode::from(code), + Ok(values) => ExitCode::from(values.status()), }) } } diff --git a/crates/lune/src/lib.rs b/crates/lune/src/lib.rs index a0fb8bf..76bbd83 100644 --- a/crates/lune/src/lib.rs +++ b/crates/lune/src/lib.rs @@ -5,4 +5,4 @@ mod rt; #[cfg(test)] mod tests; -pub use crate::rt::{Runtime, RuntimeError, RuntimeResult}; +pub use crate::rt::{Runtime, RuntimeError, RuntimeResult, RuntimeReturnValues}; diff --git a/crates/lune/src/rt/mod.rs b/crates/lune/src/rt/mod.rs index 16393f1..6e95268 100644 --- a/crates/lune/src/rt/mod.rs +++ b/crates/lune/src/rt/mod.rs @@ -2,4 +2,4 @@ mod result; mod runtime; pub use self::result::{RuntimeError, RuntimeResult}; -pub use self::runtime::Runtime; +pub use self::runtime::{Runtime, RuntimeReturnValues}; diff --git a/crates/lune/src/rt/runtime.rs b/crates/lune/src/rt/runtime.rs index 3a05243..7c45355 100644 --- a/crates/lune/src/rt/runtime.rs +++ b/crates/lune/src/rt/runtime.rs @@ -11,6 +11,46 @@ use mlua_luau_scheduler::{Functions, Scheduler}; use super::{RuntimeError, RuntimeResult}; +/** + Values returned by running a Lune runtime until completion. +*/ +#[non_exhaustive] +pub struct RuntimeReturnValues { + /// The exit code manually returned from the runtime, if any. + pub code: Option, + /// Whether any errors were thrown from threads + /// that were not the main thread, or not. + pub errored: bool, + /// The final values returned by the main thread. + pub values: LuaMultiValue, +} + +impl RuntimeReturnValues { + /** + Returns the final, combined "status" of the runtime return values. + + If no exit code was explicitly set by either the main thread, + or any threads it may have spawned, the status will be either: + + - `0` if no threads errored + - `1` if any threads errored + */ + #[must_use] + pub fn status(&self) -> u8 { + self.code.unwrap_or(u8::from(self.errored)) + } + + /** + Returns whether the run was considered successful, or not. + + See [`RuntimeReturnValues::status`] for more information. + */ + #[must_use] + pub fn success(&self) -> bool { + self.status() == 0 + } +} + /** A Lune runtime. */ @@ -125,7 +165,7 @@ impl Runtime { &mut self, script_name: impl AsRef, script_contents: impl AsRef<[u8]>, - ) -> RuntimeResult<(u8, Vec)> { + ) -> RuntimeResult { // Add error callback to format errors nicely + store status let got_any_error = Arc::new(AtomicBool::new(false)); let got_any_inner = Arc::clone(&got_any_error); @@ -148,16 +188,15 @@ impl Runtime { let main_thread_id = self.sched.push_thread_back(main, ())?; self.sched.run().await; - let main_thread_res = match self.sched.get_thread_result(main_thread_id) { + let main_thread_values = match self.sched.get_thread_result(main_thread_id) { Some(res) => res, None => LuaValue::Nil.into_lua_multi(&self.lua), }?; - Ok(( - self.sched - .get_exit_code() - .unwrap_or(u8::from(got_any_error.load(Ordering::SeqCst))), - main_thread_res.into_vec(), - )) + Ok(RuntimeReturnValues { + code: self.sched.get_exit_code(), + errored: got_any_error.load(Ordering::SeqCst), + values: main_thread_values, + }) } } diff --git a/crates/lune/src/standalone/mod.rs b/crates/lune/src/standalone/mod.rs index 2bbc7c0..6f0c0d2 100644 --- a/crates/lune/src/standalone/mod.rs +++ b/crates/lune/src/standalone/mod.rs @@ -38,6 +38,6 @@ pub async fn run(patched_bin: impl AsRef<[u8]>) -> Result { eprintln!("{err}"); ExitCode::FAILURE } - Ok((code, _)) => ExitCode::from(code), + Ok(values) => ExitCode::from(values.status()), }) } diff --git a/crates/lune/src/tests.rs b/crates/lune/src/tests.rs index e9ff03b..e4809e8 100644 --- a/crates/lune/src/tests.rs +++ b/crates/lune/src/tests.rs @@ -44,8 +44,8 @@ macro_rules! create_tests { .trim_end_matches(".luau") .trim_end_matches(".lua") .to_string(); - let (exit_code, _) = lune.run(&script_name, &script).await?; - Ok(ExitCode::from(exit_code)) + let script_values = lune.run(&script_name, &script).await?; + Ok(ExitCode::from(script_values.status())) } )* } }