From 39d66182f0290bacc10886c2659874bd9edc2d4b Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Tue, 19 May 2026 22:48:23 +0800 Subject: Add `empty_result!` macro and `REPL` resource, improve examples --- mingling_core/src/program.rs | 2 ++ mingling_core/src/program/repl_exec.rs | 24 +++++++++++++++++++++--- mingling_core/src/program/repl_exec/res.rs | 6 ++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 mingling_core/src/program/repl_exec/res.rs (limited to 'mingling_core/src') diff --git a/mingling_core/src/program.rs b/mingling_core/src/program.rs index c50e072..96b2b1a 100644 --- a/mingling_core/src/program.rs +++ b/mingling_core/src/program.rs @@ -26,6 +26,8 @@ mod once_exec; #[cfg(feature = "repl")] mod repl_exec; +#[cfg(feature = "repl")] +pub use repl_exec::res::REPL; mod single_instance; pub use single_instance::*; diff --git a/mingling_core/src/program/repl_exec.rs b/mingling_core/src/program/repl_exec.rs index 5246ece..5417252 100644 --- a/mingling_core/src/program/repl_exec.rs +++ b/mingling_core/src/program/repl_exec.rs @@ -3,11 +3,15 @@ use std::io::Write; +#[doc(hidden)] +pub mod res; + mod splitter; use crate::error::{ProgramInternalExecuteError, ProgramPanic}; use crate::program::repl_exec::splitter::split_input_string; use crate::{Program, ProgramCollect, RenderResult}; +use crate::{program::repl_exec::res::REPL, this}; #[cfg(not(feature = "async"))] impl Program @@ -18,10 +22,13 @@ where /// /// This method starts an infinite loop that continuously reads user input, parses commands, executes them, /// and displays the execution result or error message. It is suitable for scenarios requiring command-line interaction with the user. - pub fn exec_repl(self) { + pub fn exec_repl(mut self) { + // Inject default REPL resource + self.with_resource(REPL::default()); + self.run_hook_repl_on_begin(); - self.exec_wrapper(|p| -> ! { + self.exec_wrapper(|p| -> () { loop { p.run_hook_repl_pre_readline(); let readline = readline_or_empty(); @@ -38,6 +45,10 @@ where } _ => {} } + + if this::().res::().unwrap().exit { + break; + } } }); } @@ -56,9 +67,12 @@ where /// **Note:** When the `async` feature is enabled, panic unwinding is not supported. /// Any panics during command execution will result in an abort rather than being caught and handled gracefully. pub async fn exec_repl(self) { + // Inject default REPL resource + self.with_resource(REPL::default()); + self.run_hook_repl_on_begin(); - self.exec_wrapper(async |p| -> ! { + self.exec_wrapper(async |p| -> () { loop { p.run_hook_repl_pre_readline(); let readline = readline_or_empty(); @@ -72,6 +86,10 @@ where } _ => {} } + + if this::().res::().unwrap().exit { + break; + } } }) .await; diff --git a/mingling_core/src/program/repl_exec/res.rs b/mingling_core/src/program/repl_exec/res.rs new file mode 100644 index 0000000..1295652 --- /dev/null +++ b/mingling_core/src/program/repl_exec/res.rs @@ -0,0 +1,6 @@ +/// Internal resource for the REPL runtime, used to control the REPL's state during execution +#[derive(Default, Clone)] +pub struct REPL { + /// Marks whether the REPL should exit after the current loop ends + pub exit: bool, +} -- cgit