From bd4b09b06181093c95e865b04d4a9cdda7dd0728 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Tue, 19 May 2026 21:38:58 +0800 Subject: Conditionally disable panic unwind support for async feature --- mingling_core/src/program/repl_exec.rs | 53 +++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) (limited to 'mingling_core/src/program/repl_exec.rs') diff --git a/mingling_core/src/program/repl_exec.rs b/mingling_core/src/program/repl_exec.rs index f3dd9f7..5246ece 100644 --- a/mingling_core/src/program/repl_exec.rs +++ b/mingling_core/src/program/repl_exec.rs @@ -18,13 +18,6 @@ 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. - /// - /// # Important - /// - /// **REPL mode is currently only available when the `async` feature is disabled; it does not support async.** - /// - /// If the `async` feature is enabled, this method will be unavailable (as it is protected by `#[cfg(not(feature = "async"))]` conditional compilation). - /// Future versions may support asynchronous REPL, but currently only synchronous mode is supported. pub fn exec_repl(self) { self.run_hook_repl_on_begin(); @@ -50,6 +43,41 @@ where } } +#[cfg(feature = "async")] +impl Program +where + C: ProgramCollect + Send + Sync + 'static, +{ + /// Executes the REPL interactive CLI mode. + /// + /// 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. + /// + /// **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) { + self.run_hook_repl_on_begin(); + + self.exec_wrapper(async |p| -> ! { + loop { + p.run_hook_repl_pre_readline(); + let readline = readline_or_empty(); + p.run_hook_repl_post_readline(&readline); + + let args = split_input_string(readline.clone()); + + match exec_once(p, args).await { + Ok(r) => { + p.run_hook_repl_on_receive_result(&r); + } + _ => {} + } + } + }) + .await; + } +} + fn readline() -> Result { let mut input = String::new(); std::io::stdout().flush()?; @@ -99,3 +127,14 @@ where exec_result } + +#[cfg(feature = "async")] +async fn exec_once( + p: &'static Program, + args: Vec, +) -> Result +where + C: ProgramCollect + Send + Sync + 'static, +{ + super::exec::exec_with_args(p, args).await +} -- cgit