use crate::{AnyOutput, ProgramCollect}; /// Collection variants for program control instructions. /// /// Defines different forms of program control collections. pub enum ProgramControls where C: ProgramCollect, { /// Empty collection. Empty, /// A single control unit. Single(ProgramControlUnit), /// A collection of multiple control units. Multi(Vec>), } impl ProgramControls where C: ProgramCollect, { /// Returns `true` if the collection is empty. pub fn is_empty(&self) -> bool { matches!(self, ProgramControls::Empty) } } impl From<()> for ProgramControls where C: ProgramCollect, { fn from(_: ()) -> Self { Self::Empty } } impl From> for ProgramControls where C: ProgramCollect, { fn from(unit: ProgramControlUnit) -> Self { Self::Single(unit) } } impl From>> for ProgramControls where C: ProgramCollect, { fn from(units: Vec>) -> Self { Self::Multi(units) } } impl IntoIterator for ProgramControls where C: ProgramCollect, { type Item = ProgramControlUnit; type IntoIter = ProgramControlsIter; 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 where C: ProgramCollect, { inner: std::vec::IntoIter>, } impl Iterator for ProgramControlsIter where C: ProgramCollect, { type Item = ProgramControlUnit; fn next(&mut self) -> Option { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl std::iter::FusedIterator for ProgramControlsIter where C: ProgramCollect, { // 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 where C: ProgramCollect, { /// 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` to be rendered. RouteToRender(AnyOutput), /// Route to the chain processing flow. /// /// Transfers control to the next chained processor, /// carrying the `AnyOutput` that needs to be passed along. RouteToChain(AnyOutput), /// Route to the help information flow. /// /// Transfers control to the help information display module, /// carrying the `AnyOutput` containing help-related content. RouteToHelp(AnyOutput), }