1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
use crate::{AnyOutput, ChainProcess, NextProcess, 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>),
}
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()
}
}
|