@@ -40,11 +40,15 @@ pub struct InspectArgs {
4040    /// Whether to remove comments when inspecting `ir` and `irOptimized` artifact fields. 
4141#[ arg( long,  short,  help_heading = "Display options" ) ]  
4242    pub  strip_yul_comments :  bool , 
43+ 
44+     /// Whether to wrap the table to the terminal width. 
45+ #[ arg( long,  short,  help_heading = "Display options" ) ]  
46+     pub  wrap :  bool , 
4347} 
4448
4549impl  InspectArgs  { 
4650    pub  fn  run ( self )  -> Result < ( ) >  { 
47-         let  Self  {  contract,  field,  build,  strip_yul_comments }  = self ; 
51+         let  Self  {  contract,  field,  build,  strip_yul_comments,  wrap  }  = self ; 
4852
4953        trace ! ( target:  "forge" ,  ?field,  ?contract,  "running forge inspect" ) ; 
5054
@@ -83,7 +87,7 @@ impl InspectArgs {
8387        match  field { 
8488            ContractArtifactField :: Abi  => { 
8589                let  abi = artifact. abi . as_ref ( ) . ok_or_else ( || missing_error ( "ABI" ) ) ?; 
86-                 print_abi ( abi) ?; 
90+                 print_abi ( abi,  wrap ) ?; 
8791            } 
8892            ContractArtifactField :: Bytecode  => { 
8993                print_json_str ( & artifact. bytecode ,  Some ( "object" ) ) ?; 
@@ -98,13 +102,13 @@ impl InspectArgs {
98102                print_json_str ( & artifact. legacy_assembly ,  None ) ?; 
99103            } 
100104            ContractArtifactField :: MethodIdentifiers  => { 
101-                 print_method_identifiers ( & artifact. method_identifiers ) ?; 
105+                 print_method_identifiers ( & artifact. method_identifiers ,  wrap ) ?; 
102106            } 
103107            ContractArtifactField :: GasEstimates  => { 
104108                print_json ( & artifact. gas_estimates ) ?; 
105109            } 
106110            ContractArtifactField :: StorageLayout  => { 
107-                 print_storage_layout ( artifact. storage_layout . as_ref ( ) ) ?; 
111+                 print_storage_layout ( artifact. storage_layout . as_ref ( ) ,  wrap ) ?; 
108112            } 
109113            ContractArtifactField :: DevDoc  => { 
110114                print_json ( & artifact. devdoc ) ?; 
@@ -126,11 +130,11 @@ impl InspectArgs {
126130            } 
127131            ContractArtifactField :: Errors  => { 
128132                let  out = artifact. abi . as_ref ( ) . map_or ( Map :: new ( ) ,  parse_errors) ; 
129-                 print_errors_events ( & out,  true ) ?; 
133+                 print_errors_events ( & out,  true ,  wrap ) ?; 
130134            } 
131135            ContractArtifactField :: Events  => { 
132136                let  out = artifact. abi . as_ref ( ) . map_or ( Map :: new ( ) ,  parse_events) ; 
133-                 print_errors_events ( & out,  false ) ?; 
137+                 print_errors_events ( & out,  false ,  wrap ) ?; 
134138            } 
135139            ContractArtifactField :: StandardJson  => { 
136140                let  standard_json = if  let  Some ( version)  = solc_version { 
@@ -184,66 +188,70 @@ fn parse_event_params(ev_params: &[EventParam]) -> String {
184188        . join ( "," ) 
185189} 
186190
187- fn  print_abi ( abi :  & JsonAbi )  -> Result < ( ) >  { 
191+ fn  print_abi ( abi :  & JsonAbi ,   should_wrap :   bool )  -> Result < ( ) >  { 
188192    if  shell:: is_json ( )  { 
189193        return  print_json ( abi) ; 
190194    } 
191195
192196    let  headers = vec ! [ Cell :: new( "Type" ) ,  Cell :: new( "Signature" ) ,  Cell :: new( "Selector" ) ] ; 
193-     print_table ( headers,  |table| { 
194-         // Print events 
195-         for  ev in  abi. events . iter ( ) . flat_map ( |( _,  events) | events)  { 
196-             let  types = parse_event_params ( & ev. inputs ) ; 
197-             let  selector = ev. selector ( ) . to_string ( ) ; 
198-             table. add_row ( [ "event" ,  & format ! ( "{}({})" ,  ev. name,  types) ,  & selector] ) ; 
199-         } 
197+     print_table ( 
198+         headers, 
199+         |table| { 
200+             // Print events 
201+             for  ev in  abi. events . iter ( ) . flat_map ( |( _,  events) | events)  { 
202+                 let  types = parse_event_params ( & ev. inputs ) ; 
203+                 let  selector = ev. selector ( ) . to_string ( ) ; 
204+                 table. add_row ( [ "event" ,  & format ! ( "{}({})" ,  ev. name,  types) ,  & selector] ) ; 
205+             } 
200206
201-         // Print errors 
202-         for  er in  abi. errors . iter ( ) . flat_map ( |( _,  errors) | errors)  { 
203-             let  selector = er. selector ( ) . to_string ( ) ; 
204-             table. add_row ( [ 
205-                 "error" , 
206-                 & format ! ( "{}({})" ,  er. name,  get_ty_sig( & er. inputs) ) , 
207-                 & selector, 
208-             ] ) ; 
209-         } 
207+              // Print errors 
208+              for  er in  abi. errors . iter ( ) . flat_map ( |( _,  errors) | errors)  { 
209+                  let  selector = er. selector ( ) . to_string ( ) ; 
210+                  table. add_row ( [ 
211+                      "error" , 
212+                      & format ! ( "{}({})" ,  er. name,  get_ty_sig( & er. inputs) ) , 
213+                      & selector, 
214+                  ] ) ; 
215+              } 
210216
211-         // Print functions 
212-         for  func in  abi. functions . iter ( ) . flat_map ( |( _,  f) | f)  { 
213-             let  selector = func. selector ( ) . to_string ( ) ; 
214-             let  state_mut = func. state_mutability . as_json_str ( ) ; 
215-             let  func_sig = if  !func. outputs . is_empty ( )  { 
216-                 format ! ( 
217-                     "{}({}) {state_mut} returns ({})" , 
218-                     func. name, 
219-                     get_ty_sig( & func. inputs) , 
220-                     get_ty_sig( & func. outputs) 
221-                 ) 
222-             }  else  { 
223-                 format ! ( "{}({}) {state_mut}" ,  func. name,  get_ty_sig( & func. inputs) ) 
224-             } ; 
225-             table. add_row ( [ "function" ,  & func_sig,  & selector] ) ; 
226-         } 
217+              // Print functions 
218+              for  func in  abi. functions . iter ( ) . flat_map ( |( _,  f) | f)  { 
219+                  let  selector = func. selector ( ) . to_string ( ) ; 
220+                  let  state_mut = func. state_mutability . as_json_str ( ) ; 
221+                  let  func_sig = if  !func. outputs . is_empty ( )  { 
222+                      format ! ( 
223+                          "{}({}) {state_mut} returns ({})" , 
224+                          func. name, 
225+                          get_ty_sig( & func. inputs) , 
226+                          get_ty_sig( & func. outputs) 
227+                      ) 
228+                  }  else  { 
229+                      format ! ( "{}({}) {state_mut}" ,  func. name,  get_ty_sig( & func. inputs) ) 
230+                  } ; 
231+                  table. add_row ( [ "function" ,  & func_sig,  & selector] ) ; 
232+              } 
227233
228-         if  let  Some ( constructor)  = abi. constructor ( )  { 
229-             let  state_mut = constructor. state_mutability . as_json_str ( ) ; 
230-             table. add_row ( [ 
231-                 "constructor" , 
232-                 & format ! ( "constructor({}) {state_mut}" ,  get_ty_sig( & constructor. inputs) ) , 
233-                 "" , 
234-             ] ) ; 
235-         } 
234+              if  let  Some ( constructor)  = abi. constructor ( )  { 
235+                  let  state_mut = constructor. state_mutability . as_json_str ( ) ; 
236+                  table. add_row ( [ 
237+                      "constructor" , 
238+                      & format ! ( "constructor({}) {state_mut}" ,  get_ty_sig( & constructor. inputs) ) , 
239+                      "" , 
240+                  ] ) ; 
241+              } 
236242
237-         if  let  Some ( fallback)  = & abi. fallback  { 
238-             let  state_mut = fallback. state_mutability . as_json_str ( ) ; 
239-             table. add_row ( [ "fallback" ,  & format ! ( "fallback() {state_mut}" ) ,  "" ] ) ; 
240-         } 
243+              if  let  Some ( fallback)  = & abi. fallback  { 
244+                  let  state_mut = fallback. state_mutability . as_json_str ( ) ; 
245+                  table. add_row ( [ "fallback" ,  & format ! ( "fallback() {state_mut}" ) ,  "" ] ) ; 
246+              } 
241247
242-         if  let  Some ( receive)  = & abi. receive  { 
243-             let  state_mut = receive. state_mutability . as_json_str ( ) ; 
244-             table. add_row ( [ "receive" ,  & format ! ( "receive() {state_mut}" ) ,  "" ] ) ; 
245-         } 
246-     } ) 
248+             if  let  Some ( receive)  = & abi. receive  { 
249+                 let  state_mut = receive. state_mutability . as_json_str ( ) ; 
250+                 table. add_row ( [ "receive" ,  & format ! ( "receive() {state_mut}" ) ,  "" ] ) ; 
251+             } 
252+         } , 
253+         should_wrap, 
254+     ) 
247255} 
248256
249257fn  get_ty_sig ( inputs :  & [ Param ] )  -> String  { 
@@ -271,7 +279,10 @@ fn internal_ty(ty: &InternalType) -> String {
271279    } 
272280} 
273281
274- pub  fn  print_storage_layout ( storage_layout :  Option < & StorageLayout > )  -> Result < ( ) >  { 
282+ pub  fn  print_storage_layout ( 
283+     storage_layout :  Option < & StorageLayout > , 
284+     should_wrap :  bool , 
285+ )  -> Result < ( ) >  { 
275286    let  Some ( storage_layout)  = storage_layout else  { 
276287        return  Err ( missing_error ( "storage layout" ) ) ; 
277288    } ; 
@@ -289,22 +300,29 @@ pub fn print_storage_layout(storage_layout: Option<&StorageLayout>) -> Result<()
289300        Cell :: new( "Contract" ) , 
290301    ] ; 
291302
292-     print_table ( headers,  |table| { 
293-         for  slot in  & storage_layout. storage  { 
294-             let  storage_type = storage_layout. types . get ( & slot. storage_type ) ; 
295-             table. add_row ( [ 
296-                 slot. label . as_str ( ) , 
297-                 storage_type. map_or ( "?" ,  |t| & t. label ) , 
298-                 & slot. slot , 
299-                 & slot. offset . to_string ( ) , 
300-                 storage_type. map_or ( "?" ,  |t| & t. number_of_bytes ) , 
301-                 & slot. contract , 
302-             ] ) ; 
303-         } 
304-     } ) 
303+     print_table ( 
304+         headers, 
305+         |table| { 
306+             for  slot in  & storage_layout. storage  { 
307+                 let  storage_type = storage_layout. types . get ( & slot. storage_type ) ; 
308+                 table. add_row ( [ 
309+                     slot. label . as_str ( ) , 
310+                     storage_type. map_or ( "?" ,  |t| & t. label ) , 
311+                     & slot. slot , 
312+                     & slot. offset . to_string ( ) , 
313+                     storage_type. map_or ( "?" ,  |t| & t. number_of_bytes ) , 
314+                     & slot. contract , 
315+                 ] ) ; 
316+             } 
317+         } , 
318+         should_wrap, 
319+     ) 
305320} 
306321
307- fn  print_method_identifiers ( method_identifiers :  & Option < BTreeMap < String ,  String > > )  -> Result < ( ) >  { 
322+ fn  print_method_identifiers ( 
323+     method_identifiers :  & Option < BTreeMap < String ,  String > > , 
324+     should_wrap :  bool , 
325+ )  -> Result < ( ) >  { 
308326    let  Some ( method_identifiers)  = method_identifiers else  { 
309327        return  Err ( missing_error ( "method identifiers" ) ) ; 
310328    } ; 
@@ -315,14 +333,18 @@ fn print_method_identifiers(method_identifiers: &Option<BTreeMap<String, String>
315333
316334    let  headers = vec ! [ Cell :: new( "Method" ) ,  Cell :: new( "Identifier" ) ] ; 
317335
318-     print_table ( headers,  |table| { 
319-         for  ( method,  identifier)  in  method_identifiers { 
320-             table. add_row ( [ method,  identifier] ) ; 
321-         } 
322-     } ) 
336+     print_table ( 
337+         headers, 
338+         |table| { 
339+             for  ( method,  identifier)  in  method_identifiers { 
340+                 table. add_row ( [ method,  identifier] ) ; 
341+             } 
342+         } , 
343+         should_wrap, 
344+     ) 
323345} 
324346
325- fn  print_errors_events ( map :  & Map < String ,  Value > ,  is_err :  bool )  -> Result < ( ) >  { 
347+ fn  print_errors_events ( map :  & Map < String ,  Value > ,  is_err :  bool ,   should_wrap :   bool )  -> Result < ( ) >  { 
326348    if  shell:: is_json ( )  { 
327349        return  print_json ( map) ; 
328350    } 
@@ -332,17 +354,28 @@ fn print_errors_events(map: &Map<String, Value>, is_err: bool) -> Result<()> {
332354    }  else  { 
333355        vec ! [ Cell :: new( "Event" ) ,  Cell :: new( "Topic" ) ] 
334356    } ; 
335-     print_table ( headers,  |table| { 
336-         for  ( method,  selector)  in  map { 
337-             table. add_row ( [ method,  selector. as_str ( ) . unwrap ( ) ] ) ; 
338-         } 
339-     } ) 
357+     print_table ( 
358+         headers, 
359+         |table| { 
360+             for  ( method,  selector)  in  map { 
361+                 table. add_row ( [ method,  selector. as_str ( ) . unwrap ( ) ] ) ; 
362+             } 
363+         } , 
364+         should_wrap, 
365+     ) 
340366} 
341367
342- fn  print_table ( headers :  Vec < Cell > ,  add_rows :  impl  FnOnce ( & mut  Table ) )  -> Result < ( ) >  { 
368+ fn  print_table ( 
369+     headers :  Vec < Cell > , 
370+     add_rows :  impl  FnOnce ( & mut  Table ) , 
371+     should_wrap :  bool , 
372+ )  -> Result < ( ) >  { 
343373    let  mut  table = Table :: new ( ) ; 
344374    table. apply_modifier ( UTF8_ROUND_CORNERS ) ; 
345375    table. set_header ( headers) ; 
376+     if  should_wrap { 
377+         table. set_content_arrangement ( comfy_table:: ContentArrangement :: Dynamic ) ; 
378+     } 
346379    add_rows ( & mut  table) ; 
347380    sh_println ! ( "\n {table}\n " ) ?; 
348381    Ok ( ( ) ) 
0 commit comments