@@ -40,7 +40,7 @@ use crate::os::Os;
4040#[ derive( Debug , Clone , Deserialize ) ]
4141pub struct FsRead {
4242 // For batch operations
43- pub operations : Option < Vec < FsReadOperation > > ,
43+ pub operations : Vec < FsReadOperation > ,
4444 pub summary : Option < String > ,
4545}
4646
@@ -55,146 +55,129 @@ pub enum FsReadOperation {
5555
5656impl FsRead {
5757 pub async fn validate ( & mut self , os : & Os ) -> Result < ( ) > {
58- if let Some ( operations) = & mut self . operations {
59- if operations. is_empty ( ) {
60- bail ! ( "At least one operation must be provided" ) ;
61- }
62-
63- for op in operations {
64- op. validate ( os) . await ?;
65- }
66- Ok ( ( ) )
67- } else {
68- bail ! ( "'operations' field must be provided" )
58+ if self . operations . is_empty ( ) {
59+ bail ! ( "At least one operation must be provided" ) ;
60+ }
61+ for op in & mut self . operations {
62+ op. validate ( os) . await ?;
6963 }
64+ Ok ( ( ) )
7065 }
7166
7267 pub async fn queue_description ( & self , os : & Os , updates : & mut impl Write ) -> Result < ( ) > {
73- if let Some ( operations) = & self . operations {
74- if operations. len ( ) == 1 {
75- // Single operation - display without batch prefix
76- operations[ 0 ] . queue_description ( os, updates) . await
77- } else {
78- // Multiple operations - display as batch
79- queue ! (
80- updates,
81- style:: Print ( "Batch fs_read operation with " ) ,
82- style:: SetForegroundColor ( Color :: Green ) ,
83- style:: Print ( operations. len( ) ) ,
84- style:: ResetColor ,
85- style:: Print ( " operations:\n " )
86- ) ?;
87-
88- // Display purpose if available for batch operations
89- let _ = display_purpose ( self . summary . as_ref ( ) , updates) ;
90-
91- for ( i, op) in operations. iter ( ) . enumerate ( ) {
92- queue ! ( updates, style:: Print ( format!( "\n ↱ Operation {}: " , i + 1 ) ) ) ?;
93- op. queue_description ( os, updates) . await ?;
94- }
95- Ok ( ( ) )
96- }
68+ if self . operations . len ( ) == 1 {
69+ // Single operation - display without batch prefix
70+ self . operations [ 0 ] . queue_description ( os, updates) . await
9771 } else {
98- bail ! ( "'operations' field must be provided" )
72+ // Multiple operations - display as batch
73+ queue ! (
74+ updates,
75+ style:: Print ( "Batch fs_read operation with " ) ,
76+ style:: SetForegroundColor ( Color :: Green ) ,
77+ style:: Print ( self . operations. len( ) ) ,
78+ style:: ResetColor ,
79+ style:: Print ( " operations:\n " )
80+ ) ?;
81+
82+ // Display purpose if available for batch operations
83+ let _ = display_purpose ( self . summary . as_ref ( ) , updates) ;
84+
85+ for ( i, op) in self . operations . iter ( ) . enumerate ( ) {
86+ queue ! ( updates, style:: Print ( format!( "\n ↱ Operation {}: " , i + 1 ) ) ) ?;
87+ op. queue_description ( os, updates) . await ?;
88+ }
89+ Ok ( ( ) )
9990 }
10091 }
10192
10293 pub async fn invoke ( & self , os : & Os , updates : & mut impl Write ) -> Result < InvokeOutput > {
103- if let Some ( operations) = & self . operations {
104- if operations. len ( ) == 1 {
105- // Single operation - return result directly
106- operations[ 0 ] . invoke ( os, updates) . await
107- } else {
108- // Multiple operations - combine results
109- let mut combined_results = Vec :: new ( ) ;
110- let mut all_images = Vec :: new ( ) ;
111- let mut has_non_image_ops = false ;
112- let mut success_ops = 0usize ;
113- let mut failed_ops = 0usize ;
114-
115- for ( i, op) in operations. iter ( ) . enumerate ( ) {
116- match op. invoke ( os, updates) . await {
117- Ok ( result) => {
118- success_ops += 1 ;
119-
120- match & result. output {
121- OutputKind :: Text ( text) => {
122- combined_results. push ( format ! (
123- "=== Operation {} Result (Text) ===\n {}" ,
124- i + 1 ,
125- text
126- ) ) ;
127- has_non_image_ops = true ;
128- } ,
129- OutputKind :: Json ( json) => {
130- combined_results. push ( format ! (
131- "=== Operation {} Result (Json) ===\n {}" ,
132- i + 1 ,
133- serde_json:: to_string_pretty( json) ?
134- ) ) ;
135- has_non_image_ops = true ;
136- } ,
137- OutputKind :: Images ( images) => {
138- all_images. extend ( images. clone ( ) ) ;
139- combined_results. push ( format ! (
140- "=== Operation {} Result (Images) ===\n [{} images processed]" ,
141- i + 1 ,
142- images. len( )
143- ) ) ;
144- } ,
145- // This branch won't be reached because single operation execution never returns a Mixed
146- // result
147- OutputKind :: Mixed { text : _, images : _ } => { } ,
148- }
149- } ,
150-
151- Err ( err) => {
152- failed_ops += 1 ;
153- combined_results. push ( format ! ( "=== Operation {} Error ===\n {}" , i + 1 , err) ) ;
154- } ,
155- }
94+ if self . operations . len ( ) == 1 {
95+ // Single operation - return result directly
96+ self . operations [ 0 ] . invoke ( os, updates) . await
97+ } else {
98+ // Multiple operations - combine results
99+ let mut combined_results = Vec :: new ( ) ;
100+ let mut all_images = Vec :: new ( ) ;
101+ let mut has_non_image_ops = false ;
102+ let mut success_ops = 0usize ;
103+ let mut failed_ops = 0usize ;
104+
105+ for ( i, op) in self . operations . iter ( ) . enumerate ( ) {
106+ match op. invoke ( os, updates) . await {
107+ Ok ( result) => {
108+ success_ops += 1 ;
109+
110+ match & result. output {
111+ OutputKind :: Text ( text) => {
112+ combined_results. push ( format ! ( "=== Operation {} Result (Text) ===\n {}" , i + 1 , text) ) ;
113+ has_non_image_ops = true ;
114+ } ,
115+ OutputKind :: Json ( json) => {
116+ combined_results. push ( format ! (
117+ "=== Operation {} Result (Json) ===\n {}" ,
118+ i + 1 ,
119+ serde_json:: to_string_pretty( json) ?
120+ ) ) ;
121+ has_non_image_ops = true ;
122+ } ,
123+ OutputKind :: Images ( images) => {
124+ all_images. extend ( images. clone ( ) ) ;
125+ combined_results. push ( format ! (
126+ "=== Operation {} Result (Images) ===\n [{} images processed]" ,
127+ i + 1 ,
128+ images. len( )
129+ ) ) ;
130+ } ,
131+ // This branch won't be reached because single operation execution never returns a Mixed
132+ // result
133+ OutputKind :: Mixed { text : _, images : _ } => { } ,
134+ }
135+ } ,
136+
137+ Err ( err) => {
138+ failed_ops += 1 ;
139+ combined_results. push ( format ! ( "=== Operation {} Error ===\n {}" , i + 1 , err) ) ;
140+ } ,
156141 }
142+ }
157143
158- queue ! (
159- updates,
160- style:: Print ( "\n " ) ,
161- style:: Print ( CONTINUATION_LINE ) ,
162- style:: Print ( "\n " )
163- ) ?;
164- super :: queue_function_result (
165- & format ! (
166- "Summary: {} operations processed, {} successful, {} failed" ,
167- operations. len( ) ,
168- success_ops,
169- failed_ops
170- ) ,
171- updates,
172- false ,
173- true ,
174- ) ?;
175-
176- let combined_text = combined_results. join ( "\n \n " ) ;
177-
178- if !all_images. is_empty ( ) && has_non_image_ops {
179- queue ! ( updates, style:: Print ( "\n herherherherherh" ) , ) ?;
180- Ok ( InvokeOutput {
181- output : OutputKind :: Mixed {
182- text : combined_text,
183- images : all_images,
184- } ,
185- } )
186- } else if !all_images. is_empty ( ) {
187- Ok ( InvokeOutput {
188- output : OutputKind :: Images ( all_images) ,
189- } )
190- } else {
191- Ok ( InvokeOutput {
192- output : OutputKind :: Text ( combined_text) ,
193- } )
194- }
144+ queue ! (
145+ updates,
146+ style:: Print ( "\n " ) ,
147+ style:: Print ( CONTINUATION_LINE ) ,
148+ style:: Print ( "\n " )
149+ ) ?;
150+ super :: queue_function_result (
151+ & format ! (
152+ "Summary: {} operations processed, {} successful, {} failed" ,
153+ self . operations. len( ) ,
154+ success_ops,
155+ failed_ops
156+ ) ,
157+ updates,
158+ false ,
159+ true ,
160+ ) ?;
161+
162+ let combined_text = combined_results. join ( "\n \n " ) ;
163+
164+ if !all_images. is_empty ( ) && has_non_image_ops {
165+ queue ! ( updates, style:: Print ( "\n herherherherherh" ) , ) ?;
166+ Ok ( InvokeOutput {
167+ output : OutputKind :: Mixed {
168+ text : combined_text,
169+ images : all_images,
170+ } ,
171+ } )
172+ } else if !all_images. is_empty ( ) {
173+ Ok ( InvokeOutput {
174+ output : OutputKind :: Images ( all_images) ,
175+ } )
176+ } else {
177+ Ok ( InvokeOutput {
178+ output : OutputKind :: Text ( combined_text) ,
179+ } )
195180 }
196- } else {
197- bail ! ( "'operations' field must be provided" )
198181 }
199182 }
200183}
0 commit comments