@@ -7,7 +7,7 @@ use crate::{diagram::join::serialize_and_join, Builder, InputSlot, Output, Strea
7
7
use super :: {
8
8
fork_clone:: DynForkClone , impls:: DefaultImpl , split_chain, transform:: transform_output,
9
9
BuiltinTarget , Diagram , DiagramError , DiagramOperation , DiagramScope , DynInputSlot , DynOutput ,
10
- NextOperation , NodeOp , NodeRegistry , OperationId , SplitOpParams ,
10
+ NextOperation , NodeOp , NodeRegistry , OperationId , SourceOperation , SplitOpParams ,
11
11
} ;
12
12
13
13
struct Vertex < ' a > {
@@ -18,8 +18,7 @@ struct Vertex<'a> {
18
18
}
19
19
20
20
struct Edge < ' a > {
21
- /// The source of the edge, may be `None` if it comes from outside the diagram, e.g. the entry point of the diagram.
22
- source : Option < & ' a OperationId > ,
21
+ source : SourceOperation ,
23
22
target : & ' a NextOperation ,
24
23
state : EdgeState < ' a > ,
25
24
}
@@ -79,7 +78,9 @@ pub(super) fn create_workflow<'a, Streams: StreamPack>(
79
78
edges. insert (
80
79
edges. len ( ) ,
81
80
Edge {
82
- source : None ,
81
+ source : SourceOperation :: Builtin {
82
+ builtin : super :: BuiltinSource :: Start ,
83
+ } ,
83
84
target : & diagram. start ,
84
85
state : EdgeState :: Ready {
85
86
output : scope. input . into ( ) ,
@@ -95,10 +96,16 @@ pub(super) fn create_workflow<'a, Streams: StreamPack>(
95
96
96
97
let mut terminate_edges: Vec < usize > = Vec :: new ( ) ;
97
98
98
- let mut add_edge = |source : Option < & ' a OperationId > ,
99
+ let mut add_edge = |source : SourceOperation ,
99
100
target : & ' a NextOperation ,
100
101
state : EdgeState < ' a > |
101
102
-> Result < ( ) , DiagramError > {
103
+ let source_id = if let SourceOperation :: Source ( source) = & source {
104
+ Some ( source. clone ( ) )
105
+ } else {
106
+ None
107
+ } ;
108
+
102
109
edges. insert (
103
110
edges. len ( ) ,
104
111
Edge {
@@ -109,10 +116,10 @@ pub(super) fn create_workflow<'a, Streams: StreamPack>(
109
116
) ;
110
117
let new_edge_id = edges. len ( ) - 1 ;
111
118
112
- if let Some ( source ) = source {
119
+ if let Some ( source_id ) = source_id {
113
120
let source_vertex = vertices
114
- . get_mut ( source )
115
- . ok_or_else ( || DiagramError :: OperationNotFound ( source . clone ( ) ) ) ?;
121
+ . get_mut ( & source_id )
122
+ . ok_or_else ( || DiagramError :: OperationNotFound ( source_id . clone ( ) ) ) ?;
116
123
source_vertex. out_edges . push ( new_edge_id) ;
117
124
}
118
125
@@ -141,7 +148,7 @@ pub(super) fn create_workflow<'a, Streams: StreamPack>(
141
148
let n = reg. create_node ( builder, node_op. config . clone ( ) ) ?;
142
149
inputs. insert ( op_id, n. input ) ;
143
150
add_edge (
144
- Some ( op_id) ,
151
+ op_id. clone ( ) . into ( ) ,
145
152
& node_op. next ,
146
153
EdgeState :: Ready {
147
154
output : n. output . into ( ) ,
@@ -151,35 +158,39 @@ pub(super) fn create_workflow<'a, Streams: StreamPack>(
151
158
}
152
159
DiagramOperation :: ForkClone ( fork_clone_op) => {
153
160
for next_op_id in fork_clone_op. next . iter ( ) {
154
- add_edge ( Some ( op_id) , next_op_id, EdgeState :: Pending ) ?;
161
+ add_edge ( op_id. clone ( ) . into ( ) , next_op_id, EdgeState :: Pending ) ?;
155
162
}
156
163
}
157
164
DiagramOperation :: Unzip ( unzip_op) => {
158
165
for next_op_id in unzip_op. next . iter ( ) {
159
- add_edge ( Some ( op_id) , next_op_id, EdgeState :: Pending ) ?;
166
+ add_edge ( op_id. clone ( ) . into ( ) , next_op_id, EdgeState :: Pending ) ?;
160
167
}
161
168
}
162
169
DiagramOperation :: ForkResult ( fork_result_op) => {
163
- add_edge ( Some ( op_id) , & fork_result_op. ok , EdgeState :: Pending ) ?;
164
- add_edge ( Some ( op_id) , & fork_result_op. err , EdgeState :: Pending ) ?;
170
+ add_edge ( op_id. clone ( ) . into ( ) , & fork_result_op. ok , EdgeState :: Pending ) ?;
171
+ add_edge (
172
+ op_id. clone ( ) . into ( ) ,
173
+ & fork_result_op. err ,
174
+ EdgeState :: Pending ,
175
+ ) ?;
165
176
}
166
177
DiagramOperation :: Split ( split_op) => {
167
178
let next_op_ids: Vec < & NextOperation > = match & split_op. params {
168
179
SplitOpParams :: Index ( v) => v. iter ( ) . collect ( ) ,
169
180
SplitOpParams :: Key ( v) => v. values ( ) . collect ( ) ,
170
181
} ;
171
182
for next_op_id in next_op_ids {
172
- add_edge ( Some ( op_id) , next_op_id, EdgeState :: Pending ) ?;
183
+ add_edge ( op_id. clone ( ) . into ( ) , next_op_id, EdgeState :: Pending ) ?;
173
184
}
174
185
if let Some ( remaining) = & split_op. remaining {
175
- add_edge ( Some ( op_id) , & remaining, EdgeState :: Pending ) ?;
186
+ add_edge ( op_id. clone ( ) . into ( ) , & remaining, EdgeState :: Pending ) ?;
176
187
}
177
188
}
178
189
DiagramOperation :: Join ( join_op) => {
179
- add_edge ( Some ( op_id) , & join_op. next , EdgeState :: Pending ) ?;
190
+ add_edge ( op_id. clone ( ) . into ( ) , & join_op. next , EdgeState :: Pending ) ?;
180
191
}
181
192
DiagramOperation :: Transform ( transform_op) => {
182
- add_edge ( Some ( op_id) , & transform_op. next , EdgeState :: Pending ) ?;
193
+ add_edge ( op_id. clone ( ) . into ( ) , & transform_op. next , EdgeState :: Pending ) ?;
183
194
}
184
195
DiagramOperation :: Dispose => { }
185
196
}
@@ -252,23 +263,31 @@ fn connect_vertex<'a>(
252
263
if target. in_edges . is_empty ( ) {
253
264
return Err ( DiagramError :: EmptyJoin ) ;
254
265
}
255
- let outputs: Vec < DynOutput > = target
266
+ let mut outputs: HashMap < SourceOperation , DynOutput > = target
256
267
. in_edges
257
268
. iter ( )
258
269
. map ( |e| {
259
270
let edge = edges. remove ( e) . unwrap ( ) ;
260
271
match edge. state {
261
- EdgeState :: Ready { output, origin : _ } => output,
272
+ EdgeState :: Ready { output, origin : _ } => ( edge . source , output) ,
262
273
_ => panic ! ( "expected all incoming edges to be ready" ) ,
263
274
}
264
275
} )
265
276
. collect ( ) ;
266
277
278
+ let mut ordered_outputs: Vec < DynOutput > = Vec :: with_capacity ( target. in_edges . len ( ) ) ;
279
+ for source_id in join_op. order . iter ( ) {
280
+ let o = outputs
281
+ . remove ( source_id)
282
+ . ok_or ( DiagramError :: OperationNotFound ( source_id. to_string ( ) ) ) ?;
283
+ ordered_outputs. push ( o) ;
284
+ }
285
+
267
286
let joined_output = if join_op. no_serialize . unwrap_or ( false ) {
268
- let join_impl = & registry. join_impls [ & outputs [ 0 ] . type_id ] ;
269
- join_impl ( builder, outputs ) ?
287
+ let join_impl = & registry. join_impls [ & ordered_outputs [ 0 ] . type_id ] ;
288
+ join_impl ( builder, ordered_outputs ) ?
270
289
} else {
271
- serialize_and_join ( builder, registry, outputs ) ?. into ( )
290
+ serialize_and_join ( builder, registry, ordered_outputs ) ?. into ( )
272
291
} ;
273
292
274
293
let out_edge = edges. get_mut ( & target. out_edges [ 0 ] ) . unwrap ( ) ;
0 commit comments