aboutsummaryrefslogtreecommitdiff
path: root/mingling_core/src/program/repl_exec.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-24 01:27:33 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-24 01:27:33 +0800
commitc28028c69d02b723745167b23fdaf25db673a2e9 (patch)
treea0228175e280541e4d1c1364187bfad83a1578eb /mingling_core/src/program/repl_exec.rs
parentd67fec8ef6cb9c53e0480fa91d7387a9f160c2cc (diff)
refactor(once_exec, repl_exec): unify sync and async execution paths
Diffstat (limited to 'mingling_core/src/program/repl_exec.rs')
-rw-r--r--mingling_core/src/program/repl_exec.rs126
1 files changed, 41 insertions, 85 deletions
diff --git a/mingling_core/src/program/repl_exec.rs b/mingling_core/src/program/repl_exec.rs
index cbda9da..f84b291 100644
--- a/mingling_core/src/program/repl_exec.rs
+++ b/mingling_core/src/program/repl_exec.rs
@@ -13,7 +13,6 @@ use crate::program::repl_exec::splitter::split_input_string;
use crate::{Program, ProgramCollect, RenderResult};
use crate::{program::repl_exec::res::ResREPL, this};
-#[cfg(not(feature = "async"))]
impl<C> Program<C>
where
C: ProgramCollect<Enum = C> + Send + Sync + 'static,
@@ -22,106 +21,63 @@ 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.
+ ///
+ /// **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.
+ #[might_be_async::func]
pub fn exec_repl(mut self) {
// Inject default REPL resource
self.with_resource(ResREPL::default());
self.run_hook_repl_on_begin(crate::hook::HookREPLBeginInfo {});
- self.exec_wrapper(|p| -> () {
- loop {
- p.run_hook_repl_pre_readline(crate::hook::HookREPLPreReadlineInfo {});
- let mut readline = p
- .run_hook_repl_readline(crate::hook::HookREPLReadlineInfo {})
- .unwrap_or_default();
- p.run_hook_repl_post_readline(crate::hook::HookREPLPostReadlineInfo {
- line: &mut readline,
- });
-
- let args = split_input_string(readline.clone());
-
- p.run_hook_repl_pre_exec(crate::hook::HookREPLPreExecInfo { args: &args });
- match exec_once(p, args) {
- Ok(r) => {
- p.run_hook_repl_on_receive_result(
- crate::hook::HookREPLOnReceiveResultInfo { result: &r },
- );
- }
- Err(ProgramInternalExecuteError::REPLPanic(panic)) => {
- p.run_hook_repl_on_panic(crate::hook::HookREPLOnPanicInfo {
- panic: &panic,
- });
- }
- _ => {}
- }
- p.run_hook_repl_post_exec(crate::hook::HookREPLPostExecInfo {});
-
- if this::<C>().res::<ResREPL>().unwrap().exit {
- p.run_hook_repl_exit(crate::hook::HookREPLExitInfo {});
- break;
- }
-
- p.run_hook_repl_loop_once(crate::hook::HookREPLLoopOnceInfo {});
- }
- });
+ might_be_async::select!(
+ self.exec_wrapper(async |p| -> () {
+ repl_loop(p).await;
+ })
+ else
+ self.exec_wrapper(|p| -> () { repl_loop(p); }
+ )
+ );
}
}
-#[cfg(feature = "async")]
-impl<C> Program<C>
+#[might_be_async::func]
+fn repl_loop<C>(p: &'static Program<C>)
where
C: ProgramCollect<Enum = C> + 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(mut self) {
- // Inject default REPL resource
- self.with_resource(ResREPL::default());
+ loop {
+ p.run_hook_repl_pre_readline(crate::hook::HookREPLPreReadlineInfo {});
+ let mut readline = p
+ .run_hook_repl_readline(crate::hook::HookREPLReadlineInfo {})
+ .unwrap_or_default();
+ p.run_hook_repl_post_readline(crate::hook::HookREPLPostReadlineInfo {
+ line: &mut readline,
+ });
- self.run_hook_repl_on_begin(crate::hook::HookREPLBeginInfo {});
+ let args = split_input_string(readline.clone());
- self.exec_wrapper(async |p| -> () {
- loop {
- p.run_hook_repl_pre_readline(crate::hook::HookREPLPreReadlineInfo {});
- let mut readline = p
- .run_hook_repl_readline(crate::hook::HookREPLReadlineInfo {})
- .unwrap_or_default();
- p.run_hook_repl_post_readline(crate::hook::HookREPLPostReadlineInfo {
- line: &mut readline,
+ p.run_hook_repl_pre_exec(crate::hook::HookREPLPreExecInfo { args: &args });
+ match might_be_async::invoke!(exec_once(p, args)) {
+ Ok(r) => {
+ p.run_hook_repl_on_receive_result(crate::hook::HookREPLOnReceiveResultInfo {
+ result: &r,
});
-
- let args = split_input_string(readline.clone());
-
- p.run_hook_repl_pre_exec(crate::hook::HookREPLPreExecInfo { args: &args });
- match exec_once(p, args).await {
- Ok(r) => {
- p.run_hook_repl_on_receive_result(
- crate::hook::HookREPLOnReceiveResultInfo { result: &r },
- );
- }
- Err(ProgramInternalExecuteError::REPLPanic(panic)) => {
- p.run_hook_repl_on_panic(crate::hook::HookREPLOnPanicInfo {
- panic: &panic,
- });
- }
- _ => {}
- }
- p.run_hook_repl_post_exec(crate::hook::HookREPLPostExecInfo {});
-
- if this::<C>().res::<ResREPL>().unwrap().exit {
- p.run_hook_repl_exit(crate::hook::HookREPLExitInfo {});
- break;
- }
-
- p.run_hook_repl_loop_once(crate::hook::HookREPLLoopOnceInfo {});
}
- })
- .await;
+ Err(ProgramInternalExecuteError::REPLPanic(panic)) => {
+ p.run_hook_repl_on_panic(crate::hook::HookREPLOnPanicInfo { panic: &panic });
+ }
+ _ => {}
+ }
+ p.run_hook_repl_post_exec(crate::hook::HookREPLPostExecInfo {});
+
+ if this::<C>().res::<ResREPL>().unwrap().exit {
+ p.run_hook_repl_exit(crate::hook::HookREPLExitInfo {});
+ break;
+ }
+
+ p.run_hook_repl_loop_once(crate::hook::HookREPLLoopOnceInfo {});
}
}