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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
use async_trait;
use cratePoint;
use crateCtx;
use crateRunResult as Result;
use crate;
/// Define if next cicle of [Flow](crate::flow::Flow) will be executed
///
/// - If any component return <code> Ok([Next::Break]) </code> flow run will be interrupted and return Ok(Global)
/// - If all component return <code> Ok([Next::Continue]) </code> flow continue to run for a more cicle
/// - If any component return <code> Err(_) </code>, flow will be interrupted and return that Error
///
///
/// Define when a [Component] is prepared to run.
///
/// - [`Lazy`](Type::Lazy) : Wait for at least one [Package](crate::package::Package) received at each input port.
///
/// - [`Eager`](Type::Eager):
/// - Wait for at least one [Package](crate::package::Package) received at each input port.
/// - Wait for all ancestral components to run, it's means that if any
/// ancestral of this [Component] is prepared to run, this [Component] will not run.
///
/// Obs: If a [Component] does not have an [Inputs](crate::ports::Inputs) port's, it will be selected
/// as the flow's entry point, and will be executed once in the first cicle.
///
///
/// Id of a component
///
pub type Id = usize;
///
/// Define the function that will excuted when a [Component] run
///
/// Global define tha data that this component can be access,
/// the data is like a global state of Flow that any component can be read or write
///
/// A [Flow](crate::flow::Flow) hava a unique [Global](ComponentRunnable::Global) type, what means that only component
/// with the same Self::Global can be use for contruct the flow.
///
/// # Examples
/// ```
/// use rs_flow::prelude::*;
///
/// struct GlobalA;
/// struct GlobalB;
///
/// #[inputs]
/// #[outputs]
/// struct ComponentA;
///
/// #[async_trait]
/// impl ComponentRunnable for ComponentA {
/// type Global = GlobalA;
/// async fn run(&self, ctx: &mut Ctx<Self::Global>) -> Result<Next> {
/// Ok(Next::Continue)
/// }
/// }
///
/// #[inputs]
/// #[outputs]
/// struct ComponentB;
///
/// #[async_trait]
/// impl ComponentRunnable for ComponentB {
/// type Global = GlobalB;
/// async fn run(&self, ctx: &mut Ctx<Self::Global>) -> Result<Next> {
/// Ok(Next::Continue)
/// }
/// }
///
/// let mut flow = Flow::new();
/// flow = flow.add_component(Component::new(1, ComponentA)).unwrap();
///
/// // flow = flow.add_component(Component::new(2, ComponentB)).unwrap();
/// // Will fail because ComponentA and ComponentB not have same Global
///
/// ```
///
///
/// Storage the component infos:
/// - [Id] that indentify a component in a [Flow](crate::flow::Flow),
/// - [Type] of component
/// - Traits needed to run ([ComponentRunnable] + [Inputs] + [Outputs])
///
///
/// ```
/// use rs_flow::prelude::*;
///
/// struct G;
///
/// #[outputs { out1 }]
/// #[inputs { in1, in2 }]
/// struct A;
///
/// assert_eq!(A.output("out1"), 0); // first output port
/// assert_eq!(A.input("in1"), 0); // first input port
/// assert_eq!(A.input("in2"), 1); // second input port
///
/// #[async_trait]
/// impl ComponentRunnable for A {
/// type Global = G;
/// async fn run(&self, ctx: &mut Ctx<Self::Global>) -> Result<Next> {
/// return Ok(Next::Continue);
/// }
/// }
/// let component1 = Component::new(1, A); // Type::Lazy
/// let component2 = Component::eager(2, A); // Type::Eeager
///
/// assert_eq!(component1.ty(), Type::Lazy);
/// assert_eq!(component2.ty(), Type::Eager);
///
/// let c = Connection::by(component1.from("out1"), component2.to("in1"));
/// assert_eq!(Connection::new(1, 0, 2, 0), c);
///
/// ```