aboutsummaryrefslogtreecommitdiff
path: root/mingling_core/src/program/hook
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-24 12:01:38 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-24 12:01:38 +0800
commit1d1baf75a3acb5eb32913a8bdad42bae42844aa2 (patch)
tree5dafbcbce48a5de3c61bba0c7d309e97dd80b1ce /mingling_core/src/program/hook
parentaddfbbf0b33a6251605990da73c2de5131766827 (diff)
Redesign hook system with structured info types and ProgramControls
Diffstat (limited to 'mingling_core/src/program/hook')
-rw-r--r--mingling_core/src/program/hook/control_unit.rs140
-rw-r--r--mingling_core/src/program/hook/hook_info.rs119
2 files changed, 259 insertions, 0 deletions
diff --git a/mingling_core/src/program/hook/control_unit.rs b/mingling_core/src/program/hook/control_unit.rs
new file mode 100644
index 0000000..b35cf3d
--- /dev/null
+++ b/mingling_core/src/program/hook/control_unit.rs
@@ -0,0 +1,140 @@
+use crate::{AnyOutput, ProgramCollect};
+
+/// Collection variants for program control instructions.
+///
+/// Defines different forms of program control collections.
+pub enum ProgramControls<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ /// Empty collection.
+ Empty,
+
+ /// A single control unit.
+ Single(ProgramControlUnit<C>),
+
+ /// A collection of multiple control units.
+ Multi(Vec<ProgramControlUnit<C>>),
+}
+
+impl<C> ProgramControls<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ /// Returns `true` if the collection is empty.
+ pub fn is_empty(&self) -> bool {
+ matches!(self, ProgramControls::Empty)
+ }
+}
+
+impl<C> From<()> for ProgramControls<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ fn from(_: ()) -> Self {
+ Self::Empty
+ }
+}
+
+impl<C> From<ProgramControlUnit<C>> for ProgramControls<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ fn from(unit: ProgramControlUnit<C>) -> Self {
+ Self::Single(unit)
+ }
+}
+
+impl<C> From<Vec<ProgramControlUnit<C>>> for ProgramControls<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ fn from(units: Vec<ProgramControlUnit<C>>) -> Self {
+ Self::Multi(units)
+ }
+}
+
+impl<C> IntoIterator for ProgramControls<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ type Item = ProgramControlUnit<C>;
+ type IntoIter = ProgramControlsIter<C>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ match self {
+ ProgramControls::Empty => ProgramControlsIter {
+ inner: vec![].into_iter(),
+ },
+ ProgramControls::Single(unit) => ProgramControlsIter {
+ inner: vec![unit].into_iter(),
+ },
+ ProgramControls::Multi(units) => ProgramControlsIter {
+ inner: units.into_iter(),
+ },
+ }
+ }
+}
+
+/// An iterator over [`ProgramControlUnit`] values.
+pub struct ProgramControlsIter<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ inner: std::vec::IntoIter<ProgramControlUnit<C>>,
+}
+
+impl<C> Iterator for ProgramControlsIter<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ type Item = ProgramControlUnit<C>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<C> std::iter::FusedIterator for ProgramControlsIter<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ // Auto impl
+}
+
+/// Enumeration of program control units.
+///
+/// Defines the various control flow instructions that a program may encounter during execution,
+/// used to alter the default execution flow (e.g., interruption, jump, or redirection).
+pub enum ProgramControlUnit<C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ /// Override the program exit code.
+ ///
+ /// Used when a non-default process exit code needs to be forcibly specified.
+ /// The contained `i32` value is the exit code to be set.
+ OverrideExitCode(i32),
+
+ /// Route to the render flow.
+ ///
+ /// Transfers control to the rendering (output) stage,
+ /// carrying the `AnyOutput<C>` to be rendered.
+ RouteToRender(AnyOutput<C>),
+
+ /// Route to the chain processing flow.
+ ///
+ /// Transfers control to the next chained processor,
+ /// carrying the `AnyOutput<C>` that needs to be passed along.
+ RouteToChain(AnyOutput<C>),
+
+ /// Route to the help information flow.
+ ///
+ /// Transfers control to the help information display module,
+ /// carrying the `AnyOutput<C>` containing help-related content.
+ RouteToHelp(AnyOutput<C>),
+}
diff --git a/mingling_core/src/program/hook/hook_info.rs b/mingling_core/src/program/hook/hook_info.rs
index e69de29..060e368 100644
--- a/mingling_core/src/program/hook/hook_info.rs
+++ b/mingling_core/src/program/hook/hook_info.rs
@@ -0,0 +1,119 @@
+use crate::{AnyOutput, ProgramCollect, RenderResult};
+
+/// Represents the data passed to `begin` hook.
+pub struct HookBeginInfo {}
+
+/// Represents the data passed to `pre_dispatch` hook.
+pub struct HookPreDispatchInfo<'a> {
+ /// Arguments entered by the user before dispatching
+ pub arguments: &'a [String],
+}
+
+/// Represents the data passed to `post_dispatch` hook.
+pub struct HookPostDispatchInfo<'a, C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ /// The entry point of dispatching
+ pub entry: &'a C,
+}
+
+/// Represents the data passed to `pre_chain` hook.
+pub struct HookPreChainInfo<'a, C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ /// Input to the chain
+ pub input: &'a C,
+
+ /// Raw data
+ pub raw: &'a dyn std::any::Any,
+}
+
+/// Represents the data passed to `post_chain` hook.
+pub struct HookPostChainInfo<'a, C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ /// Output of the chain
+ pub output: &'a AnyOutput<C>,
+}
+
+/// Represents the data passed to `pre_render` hook.
+pub struct HookPreRenderInfo<'a, C>
+where
+ C: ProgramCollect<Enum = C>,
+{
+ /// Render input
+ pub input: &'a C,
+
+ /// The raw data to be rendered
+ pub raw: &'a dyn std::any::Any,
+}
+
+/// Represents the data passed to `post_render` hook.
+pub struct HookPostRenderInfo<'a> {
+ /// The rendering result
+ pub result: &'a RenderResult,
+}
+
+/// Represents the data passed to `finish` hook.
+pub struct HookFinishInfo {}
+
+/// Represents the data passed to `exec_panic` hook.
+#[cfg(not(feature = "async"))]
+pub struct HookPanicInfo<'a> {
+ /// Raw data of the panic
+ pub panic: &'a crate::error::ProgramPanic,
+}
+
+#[cfg(feature = "repl")]
+mod repl_hook {
+ use crate::RenderResult;
+
+ /// Represents the data passed to `repl_on_begin` hook.
+ pub struct HookREPLBeginInfo {}
+
+ /// Represents the data passed to `repl_pre_readline` hook.
+ pub struct HookREPLPreReadlineInfo {}
+
+ /// Represents the data passed to `repl_readline` hook.
+ pub struct HookREPLReadlineInfo {}
+
+ /// Represents the data passed to `repl_post_readline` hook.
+ pub struct HookREPLPostReadlineInfo<'a> {
+ /// The read line (mutable for editing)
+ pub line: &'a mut String,
+ }
+
+ /// Represents the data passed to `repl_pre_exec` hook.
+ pub struct HookREPLPreExecInfo<'a> {
+ /// Arguments for the command
+ pub args: &'a [String],
+ }
+
+ /// Represents the data passed to `repl_post_exec` hook.
+ pub struct HookREPLPostExecInfo {}
+
+ /// Represents the data passed to `repl_on_receive_result` hook.
+ pub struct HookREPLOnReceiveResultInfo<'a> {
+ /// The rendering result
+ pub result: &'a RenderResult,
+ }
+
+ /// Represents the data passed to `repl_exit` hook.
+ pub struct HookREPLExitInfo {}
+
+ /// Represents the data passed to `repl_loop_once` hook.
+ pub struct HookREPLLoopOnceInfo {}
+
+ /// Represents the data passed to `repl_on_panic` hook.
+ #[cfg(not(feature = "async"))]
+ pub struct HookREPLOnPanicInfo<'a> {
+ /// Raw data of the panic
+ pub panic: &'a crate::error::ProgramPanic,
+ }
+}
+
+#[cfg(feature = "repl")]
+pub use repl_hook::*;