aboutsummaryrefslogtreecommitdiff
path: root/mingling_core/src
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-24 13:56:32 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-24 14:19:48 +0800
commit7cae57eedeb3a3bca0525faaa139e3df96d0456a (patch)
tree50a16fc177b7d8d8f02aad40b130bc611a8a7f28 /mingling_core/src
parent1d1baf75a3acb5eb32913a8bdad42bae42844aa2 (diff)
Pass current context through hook control and support conversion
Diffstat (limited to 'mingling_core/src')
-rw-r--r--mingling_core/src/program/exec.rs306
-rw-r--r--mingling_core/src/program/hook/control_unit.rs27
2 files changed, 216 insertions, 117 deletions
diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs
index 0ade92f..1832430 100644
--- a/mingling_core/src/program/exec.rs
+++ b/mingling_core/src/program/exec.rs
@@ -37,20 +37,31 @@ where
// Exit code
let mut exit_code: i32 = 0;
- // Current
- let mut current = C::build_dispatcher_not_found(vec![]);
-
macro_rules! control {
+ ($hook_call:expr, $current:expr) => {
+ let __ccc = $hook_call;
+ if let Some(r) =
+ handle_program_control(program, __ccc, Some(&mut $current), &mut exit_code)
+ {
+ return Ok(r);
+ }
+ };
($hook_call:expr) => {
let __ccc = $hook_call;
- if let Some(r) = handle_program_control(program, __ccc, &mut current, &mut exit_code) {
+ if let Some(r) = handle_program_control(program, __ccc, None, &mut exit_code) {
return Ok(r);
}
};
}
+ // Current
+ let mut current = C::build_dispatcher_not_found(vec![]);
+
// Run hooks
- control!(program.run_hook_pre_dispatch(crate::hook::HookPreDispatchInfo { arguments: args }));
+ control!(
+ program.run_hook_pre_dispatch(crate::hook::HookPreDispatchInfo { arguments: args }),
+ current
+ );
// Dispatch args - either via dynamic dispatch or trie dispatch based on feature flag
let mut current = if cfg!(not(feature = "dispatch_tree")) {
@@ -63,7 +74,8 @@ where
control!(
program.run_hook_post_dispatch(crate::hook::HookPostDispatchInfo {
entry: &current.member_id,
- })
+ }),
+ current
);
let mut stop_next = false;
@@ -75,74 +87,88 @@ where
// Run hook
control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
render_result.exit_code = exit_code;
+
return Ok(render_result);
}
loop {
let final_exec = stop_next;
- current =
- {
- // If a chain exists, execute as a chain
- if C::has_chain(&current) {
- // Run hook
- control!(program.run_hook_pre_chain(crate::hook::HookPreChainInfo {
+ current = {
+ // If a chain exists, execute as a chain
+ if C::has_chain(&current) {
+ // Run hook
+ control!(
+ program.run_hook_pre_chain(crate::hook::HookPreChainInfo {
input: &current.member_id,
raw: current.inner.as_ref(),
- }));
-
- match C::do_chain(current).await {
- ChainProcess::Ok((any, NextProcess::Renderer)) => {
- {
- let mut render_result = render::<C>(program, any);
-
- // Run hook
- control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
- render_result.exit_code = exit_code;
- return Ok(render_result);
- };
- }
- ChainProcess::Ok((any, NextProcess::Chain)) => {
+ }),
+ current
+ );
+
+ match C::do_chain(current).await {
+ ChainProcess::Ok((any, NextProcess::Renderer)) => {
+ {
+ let mut render_result = render::<C>(program, any);
+
// Run hook
- control!(program.run_hook_post_chain(crate::hook::HookPostChainInfo {
+ control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
+ render_result.exit_code = exit_code;
+
+ return Ok(render_result);
+ };
+ }
+ ChainProcess::Ok((mut any, NextProcess::Chain)) => {
+ // Run hook
+ control!(
+ program.run_hook_post_chain(crate::hook::HookPostChainInfo {
output: &any
- }));
+ }),
any
- }
- ChainProcess::Err(e) => {
- // Run hook
- control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
- return Err(e.into());
- }
+ );
+ any
+ }
+ ChainProcess::Err(e) => {
+ // Run hook
+ control!(
+ program.run_hook_finish(crate::hook::HookFinishInfo {}),
+ &mut C::build_empty_result()
+ );
+ return Err(e.into());
}
}
- // If no chain exists, attempt to render
- else if C::has_renderer(&current) {
- // Run hook
- control!(program.run_hook_pre_render(crate::hook::HookPreRenderInfo {
+ }
+ // If no chain exists, attempt to render
+ else if C::has_renderer(&current) {
+ // Run hook
+ control!(
+ program.run_hook_pre_render(crate::hook::HookPreRenderInfo {
input: &current.member_id,
raw: current.inner.as_ref(),
- }));
+ }),
+ current
+ );
- let mut render_result = render::<C>(program, current);
+ let mut render_result = render::<C>(program, current);
- // Run hooks
- control!(
- program.run_hook_post_render(crate::hook::HookPostRenderInfo {
- result: &render_result,
- })
- );
+ // Run hooks
+ control!(
+ program.run_hook_post_render(crate::hook::HookPostRenderInfo {
+ result: &render_result,
+ })
+ );
- control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
- render_result.exit_code = exit_code;
- return Ok(render_result);
- }
- // No renderer exists
- else {
- stop_next = true;
- C::build_renderer_not_found(current.member_id)
- }
- };
+ control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
+
+ render_result.exit_code = exit_code;
+ return Ok(render_result);
+ }
+ // No renderer exists
+ else {
+ stop_next = true;
+ C::build_renderer_not_found(current.member_id)
+ }
+ };
if final_exec && stop_next {
break;
@@ -151,7 +177,10 @@ where
let mut render_result = RenderResult::default();
// Run hook
- control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
+ control!(
+ program.run_hook_finish(crate::hook::HookFinishInfo {}),
+ current
+ );
render_result.exit_code = exit_code;
Ok(render_result)
}
@@ -167,20 +196,31 @@ where
// Exit code
let mut exit_code: i32 = 0;
- // Current
- let mut current = C::build_dispatcher_not_found(vec![]);
-
macro_rules! control {
+ ($hook_call:expr, $current:expr) => {
+ let __ccc = $hook_call;
+ if let Some(r) =
+ handle_program_control(program, __ccc, Some(&mut $current), &mut exit_code)
+ {
+ return Ok(r);
+ }
+ };
($hook_call:expr) => {
let __ccc = $hook_call;
- if let Some(r) = handle_program_control(program, __ccc, &mut current, &mut exit_code) {
+ if let Some(r) = handle_program_control(program, __ccc, None, &mut exit_code) {
return Ok(r);
}
};
}
+ // Current
+ let mut current = C::build_dispatcher_not_found(vec![]);
+
// Run hooks
- control!(program.run_hook_pre_dispatch(crate::hook::HookPreDispatchInfo { arguments: args }));
+ control!(
+ program.run_hook_pre_dispatch(crate::hook::HookPreDispatchInfo { arguments: args }),
+ current
+ );
// Dispatch args - either via dynamic dispatch or trie dispatch based on feature flag
let mut current = if cfg!(not(feature = "dispatch_tree")) {
@@ -193,7 +233,8 @@ where
control!(
program.run_hook_post_dispatch(crate::hook::HookPostDispatchInfo {
entry: &current.member_id,
- })
+ }),
+ current
);
let mut stop_next = false;
@@ -205,74 +246,88 @@ where
// Run hook
control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
render_result.exit_code = exit_code;
+
return Ok(render_result);
}
loop {
let final_exec = stop_next;
- current =
- {
- // If a chain exists, execute as a chain
- if C::has_chain(&current) {
- // Run hook
- control!(program.run_hook_pre_chain(crate::hook::HookPreChainInfo {
+ current = {
+ // If a chain exists, execute as a chain
+ if C::has_chain(&current) {
+ // Run hook
+ control!(
+ program.run_hook_pre_chain(crate::hook::HookPreChainInfo {
input: &current.member_id,
raw: current.inner.as_ref(),
- }));
-
- match C::do_chain(current) {
- ChainProcess::Ok((any, NextProcess::Renderer)) => {
- {
- let mut render_result = render::<C>(program, any);
-
- // Run hook
- control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
- render_result.exit_code = exit_code;
- return Ok(render_result);
- };
- }
- ChainProcess::Ok((any, NextProcess::Chain)) => {
+ }),
+ current
+ );
+
+ match C::do_chain(current) {
+ ChainProcess::Ok((any, NextProcess::Renderer)) => {
+ {
+ let mut render_result = render::<C>(program, any);
+
// Run hook
- control!(program.run_hook_post_chain(crate::hook::HookPostChainInfo {
+ control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
+ render_result.exit_code = exit_code;
+
+ return Ok(render_result);
+ };
+ }
+ ChainProcess::Ok((mut any, NextProcess::Chain)) => {
+ // Run hook
+ control!(
+ program.run_hook_post_chain(crate::hook::HookPostChainInfo {
output: &any
- }));
+ }),
any
- }
- ChainProcess::Err(e) => {
- // Run hook
- control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
- return Err(e.into());
- }
+ );
+ any
+ }
+ ChainProcess::Err(e) => {
+ // Run hook
+ control!(
+ program.run_hook_finish(crate::hook::HookFinishInfo {}),
+ &mut C::build_empty_result()
+ );
+ return Err(e.into());
}
}
- // If no chain exists, attempt to render
- else if C::has_renderer(&current) {
- // Run hook
- control!(program.run_hook_pre_render(crate::hook::HookPreRenderInfo {
+ }
+ // If no chain exists, attempt to render
+ else if C::has_renderer(&current) {
+ // Run hook
+ control!(
+ program.run_hook_pre_render(crate::hook::HookPreRenderInfo {
input: &current.member_id,
raw: current.inner.as_ref(),
- }));
+ }),
+ current
+ );
- let mut render_result = render::<C>(program, current);
+ let mut render_result = render::<C>(program, current);
- // Run hooks
- control!(
- program.run_hook_post_render(crate::hook::HookPostRenderInfo {
- result: &render_result,
- })
- );
+ // Run hooks
+ control!(
+ program.run_hook_post_render(crate::hook::HookPostRenderInfo {
+ result: &render_result,
+ })
+ );
- control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
- render_result.exit_code = exit_code;
- return Ok(render_result);
- }
- // No renderer exists
- else {
- stop_next = true;
- C::build_renderer_not_found(current.member_id)
- }
- };
+ control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
+
+ render_result.exit_code = exit_code;
+ return Ok(render_result);
+ }
+ // No renderer exists
+ else {
+ stop_next = true;
+ C::build_renderer_not_found(current.member_id)
+ }
+ };
if final_exec && stop_next {
break;
@@ -281,7 +336,10 @@ where
let mut render_result = RenderResult::default();
// Run hook
- control!(program.run_hook_finish(crate::hook::HookFinishInfo {}));
+ control!(
+ program.run_hook_finish(crate::hook::HookFinishInfo {}),
+ current
+ );
render_result.exit_code = exit_code;
Ok(render_result)
}
@@ -360,16 +418,32 @@ where
pub(crate) fn handle_program_control<C: ProgramCollect<Enum = C>>(
program: &Program<C>,
controls: ProgramControls<C>,
- current: &mut AnyOutput<C>,
+ mut current: Option<&mut AnyOutput<C>>,
exit_code: &mut i32,
) -> Option<RenderResult> {
for unit in controls.into_iter() {
match unit {
super::hook::ProgramControlUnit::OverrideExitCode(c) => *exit_code = c,
- super::hook::ProgramControlUnit::RouteToChain(any_output) => *current = any_output,
+ super::hook::ProgramControlUnit::RouteToChain(any_output) => {
+ if let Some(ref mut current) = current {
+ **current = any_output;
+ }
+ }
super::hook::ProgramControlUnit::RouteToRender(any_output) => {
+ // Note: Hooks triggered by ProgramControl will not trigger ProgramControl again
+
+ // Pre render
+ let _ = program.run_hook_pre_render(crate::hook::HookPreRenderInfo {
+ input: &any_output.member_id,
+ raw: any_output.inner.as_ref(),
+ });
+
let mut r = render::<C>(program, any_output);
r.exit_code = *exit_code;
+
+ // Post render
+ program.run_hook_post_render(crate::hook::HookPostRenderInfo { result: &r });
+
return Some(r);
}
super::hook::ProgramControlUnit::RouteToHelp(any_output) => {
diff --git a/mingling_core/src/program/hook/control_unit.rs b/mingling_core/src/program/hook/control_unit.rs
index b35cf3d..5bf0e8c 100644
--- a/mingling_core/src/program/hook/control_unit.rs
+++ b/mingling_core/src/program/hook/control_unit.rs
@@ -1,4 +1,4 @@
-use crate::{AnyOutput, ProgramCollect};
+use crate::{AnyOutput, ChainProcess, NextProcess, ProgramCollect};
/// Collection variants for program control instructions.
///
@@ -138,3 +138,28 @@ where
/// carrying the `AnyOutput<C>` containing help-related content.
RouteToHelp(AnyOutput<C>),
}
+
+impl<C> From<ChainProcess<C>> for ProgramControlUnit<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ fn from(val: ChainProcess<C>) -> Self {
+ match val {
+ ChainProcess::Ok((any, next)) => match next {
+ NextProcess::Chain => ProgramControlUnit::RouteToChain(any),
+ NextProcess::Renderer => ProgramControlUnit::RouteToRender(any),
+ },
+ ChainProcess::Err(e) => panic!("{}", &e),
+ }
+ }
+}
+
+impl<C> From<ChainProcess<C>> for ProgramControls<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ fn from(val: ChainProcess<C>) -> Self {
+ let unit: ProgramControlUnit<C> = val.into();
+ unit.into()
+ }
+}