diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-06-24 12:01:38 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-06-24 12:01:38 +0800 |
| commit | 1d1baf75a3acb5eb32913a8bdad42bae42844aa2 (patch) | |
| tree | 5dafbcbce48a5de3c61bba0c7d309e97dd80b1ce /mingling_core/src/program/hook | |
| parent | addfbbf0b33a6251605990da73c2de5131766827 (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.rs | 140 | ||||
| -rw-r--r-- | mingling_core/src/program/hook/hook_info.rs | 119 |
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::*; |
