@@ -156,24 +156,6 @@ impl DataSlice {
156156 data_type : field_schema. value_type . clone ( ) . into ( ) ,
157157 } ) )
158158 }
159-
160- pub fn table_row_scope ( & self ) -> PyResult < OpScopeRef > {
161- let field_path = match self . value . as_ref ( ) {
162- spec:: ValueMapping :: Field ( v) => & v. field_path ,
163- _ => return Err ( PyException :: new_err ( "expect field path" ) ) ,
164- } ;
165- let num_parent_layers = self . scope . ancestors ( ) . count ( ) ;
166- let scope_name = format ! (
167- "{}_{}" ,
168- field_path. last( ) . map_or( "" , |s| s. as_str( ) ) ,
169- num_parent_layers
170- ) ;
171- let ( _, sub_op_scope) = self
172- . scope
173- . new_foreach_op_scope ( scope_name, field_path)
174- . into_py_result ( ) ?;
175- Ok ( OpScopeRef ( sub_op_scope) )
176- }
177159}
178160
179161impl DataSlice {
@@ -383,6 +365,48 @@ impl FlowBuilder {
383365 Ok ( ( ) )
384366 }
385367
368+ #[ pyo3( signature = ( data_slice, execution_options=None ) ) ]
369+ pub fn for_each (
370+ & mut self ,
371+ data_slice : DataSlice ,
372+ execution_options : Option < py:: Pythonized < spec:: ExecutionOptions > > ,
373+ ) -> PyResult < OpScopeRef > {
374+ let parent_scope = & data_slice. scope ;
375+ let field_path = match data_slice. value . as_ref ( ) {
376+ spec:: ValueMapping :: Field ( v) => & v. field_path ,
377+ _ => return Err ( PyException :: new_err ( "expect field path" ) ) ,
378+ } ;
379+ let num_parent_layers = parent_scope. ancestors ( ) . count ( ) ;
380+ let scope_name = format ! (
381+ "{}_{}" ,
382+ field_path. last( ) . map_or( "" , |s| s. as_str( ) ) ,
383+ num_parent_layers
384+ ) ;
385+ let ( _, child_op_scope) = parent_scope
386+ . new_foreach_op_scope ( scope_name. clone ( ) , field_path)
387+ . into_py_result ( ) ?;
388+
389+ let reactive_op = spec:: NamedSpec {
390+ name : format ! ( ".for_each.{}" , self . next_generated_op_id) ,
391+ spec : spec:: ReactiveOpSpec :: ForEach ( spec:: ForEachOpSpec {
392+ field_path : field_path. clone ( ) ,
393+ op_scope : spec:: ReactiveOpScope {
394+ name : scope_name,
395+ ops : vec ! [ ] ,
396+ } ,
397+ execution_options : execution_options
398+ . map ( |o| o. into_inner ( ) )
399+ . unwrap_or_default ( ) ,
400+ } ) ,
401+ } ;
402+ self . next_generated_op_id += 1 ;
403+ self . get_mut_reactive_ops ( parent_scope)
404+ . into_py_result ( ) ?
405+ . push ( reactive_op) ;
406+
407+ Ok ( OpScopeRef ( child_op_scope) )
408+ }
409+
386410 #[ pyo3( signature = ( kind, op_spec, args, target_scope, name) ) ]
387411 pub fn transform (
388412 & mut self ,
@@ -428,7 +452,9 @@ impl FlowBuilder {
428452 . into_py_result ( ) ?;
429453 std:: mem:: drop ( analyzed) ;
430454
431- self . get_mut_reactive_ops ( op_scope) . push ( reactive_op) ;
455+ self . get_mut_reactive_ops ( op_scope)
456+ . into_py_result ( ) ?
457+ . push ( reactive_op) ;
432458
433459 let result = Self :: last_field_to_data_slice ( op_scope) . into_py_result ( ) ?;
434460 Ok ( result)
@@ -476,7 +502,9 @@ impl FlowBuilder {
476502 . into_py_result ( ) ?;
477503 std:: mem:: drop ( analyzed) ;
478504
479- self . get_mut_reactive_ops ( common_scope) . push ( reactive_op) ;
505+ self . get_mut_reactive_ops ( common_scope)
506+ . into_py_result ( ) ?
507+ . push ( reactive_op) ;
480508
481509 let collector_schema = CollectorSchema :: from_fields (
482510 fields
@@ -741,27 +769,19 @@ impl FlowBuilder {
741769 fn get_mut_reactive_ops < ' a > (
742770 & ' a mut self ,
743771 op_scope : & OpScope ,
744- ) -> & ' a mut Vec < spec:: NamedSpec < spec:: ReactiveOpSpec > > {
745- Self :: get_mut_reactive_ops_internal (
746- op_scope,
747- & mut self . reactive_ops ,
748- & mut self . next_generated_op_id ,
749- )
772+ ) -> Result < & ' a mut Vec < spec:: NamedSpec < spec:: ReactiveOpSpec > > > {
773+ Self :: get_mut_reactive_ops_internal ( op_scope, & mut self . reactive_ops )
750774 }
751775
752776 fn get_mut_reactive_ops_internal < ' a > (
753777 op_scope : & OpScope ,
754778 root_reactive_ops : & ' a mut Vec < spec:: NamedSpec < spec:: ReactiveOpSpec > > ,
755- next_generated_op_id : & mut usize ,
756- ) -> & ' a mut Vec < spec:: NamedSpec < spec:: ReactiveOpSpec > > {
757- match & op_scope. parent {
779+ ) -> Result < & ' a mut Vec < spec:: NamedSpec < spec:: ReactiveOpSpec > > > {
780+ let result = match & op_scope. parent {
758781 None => root_reactive_ops,
759782 Some ( ( parent_op_scope, field_path) ) => {
760- let parent_reactive_ops = Self :: get_mut_reactive_ops_internal (
761- parent_op_scope,
762- root_reactive_ops,
763- next_generated_op_id,
764- ) ;
783+ let parent_reactive_ops =
784+ Self :: get_mut_reactive_ops_internal ( parent_op_scope, root_reactive_ops) ?;
765785 // Reuse the last foreach if matched, otherwise create a new one.
766786 match parent_reactive_ops. last ( ) {
767787 Some ( spec:: NamedSpec {
@@ -771,24 +791,15 @@ impl FlowBuilder {
771791 && foreach_spec. op_scope . name == op_scope. name => { }
772792
773793 _ => {
774- parent_reactive_ops. push ( spec:: NamedSpec {
775- name : format ! ( ".foreach.{}" , next_generated_op_id) ,
776- spec : spec:: ReactiveOpSpec :: ForEach ( spec:: ForEachOpSpec {
777- field_path : field_path. clone ( ) ,
778- op_scope : spec:: ReactiveOpScope {
779- name : op_scope. name . clone ( ) ,
780- ops : vec ! [ ] ,
781- } ,
782- } ) ,
783- } ) ;
784- * next_generated_op_id += 1 ;
794+ api_bail ! ( "already out of op scope `{}`" , op_scope. name) ;
785795 }
786796 }
787797 match & mut parent_reactive_ops. last_mut ( ) . unwrap ( ) . spec {
788798 spec:: ReactiveOpSpec :: ForEach ( foreach_spec) => & mut foreach_spec. op_scope . ops ,
789799 _ => unreachable ! ( ) ,
790800 }
791801 }
792- }
802+ } ;
803+ Ok ( result)
793804 }
794805}
0 commit comments