@@ -40,11 +40,15 @@ pub struct InspectArgs {
40
40
/// Whether to remove comments when inspecting `ir` and `irOptimized` artifact fields.
41
41
#[ arg( long, short, help_heading = "Display options" ) ]
42
42
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 ,
43
47
}
44
48
45
49
impl InspectArgs {
46
50
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 ;
48
52
49
53
trace ! ( target: "forge" , ?field, ?contract, "running forge inspect" ) ;
50
54
@@ -83,7 +87,7 @@ impl InspectArgs {
83
87
match field {
84
88
ContractArtifactField :: Abi => {
85
89
let abi = artifact. abi . as_ref ( ) . ok_or_else ( || missing_error ( "ABI" ) ) ?;
86
- print_abi ( abi) ?;
90
+ print_abi ( abi, wrap ) ?;
87
91
}
88
92
ContractArtifactField :: Bytecode => {
89
93
print_json_str ( & artifact. bytecode , Some ( "object" ) ) ?;
@@ -98,13 +102,13 @@ impl InspectArgs {
98
102
print_json_str ( & artifact. legacy_assembly , None ) ?;
99
103
}
100
104
ContractArtifactField :: MethodIdentifiers => {
101
- print_method_identifiers ( & artifact. method_identifiers ) ?;
105
+ print_method_identifiers ( & artifact. method_identifiers , wrap ) ?;
102
106
}
103
107
ContractArtifactField :: GasEstimates => {
104
108
print_json ( & artifact. gas_estimates ) ?;
105
109
}
106
110
ContractArtifactField :: StorageLayout => {
107
- print_storage_layout ( artifact. storage_layout . as_ref ( ) ) ?;
111
+ print_storage_layout ( artifact. storage_layout . as_ref ( ) , wrap ) ?;
108
112
}
109
113
ContractArtifactField :: DevDoc => {
110
114
print_json ( & artifact. devdoc ) ?;
@@ -126,11 +130,11 @@ impl InspectArgs {
126
130
}
127
131
ContractArtifactField :: Errors => {
128
132
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 ) ?;
130
134
}
131
135
ContractArtifactField :: Events => {
132
136
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 ) ?;
134
138
}
135
139
ContractArtifactField :: StandardJson => {
136
140
let standard_json = if let Some ( version) = solc_version {
@@ -184,66 +188,70 @@ fn parse_event_params(ev_params: &[EventParam]) -> String {
184
188
. join ( "," )
185
189
}
186
190
187
- fn print_abi ( abi : & JsonAbi ) -> Result < ( ) > {
191
+ fn print_abi ( abi : & JsonAbi , should_wrap : bool ) -> Result < ( ) > {
188
192
if shell:: is_json ( ) {
189
193
return print_json ( abi) ;
190
194
}
191
195
192
196
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
+ }
200
206
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
+ }
210
216
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
+ }
227
233
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
+ }
236
242
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
+ }
241
247
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
+ )
247
255
}
248
256
249
257
fn get_ty_sig ( inputs : & [ Param ] ) -> String {
@@ -271,7 +279,10 @@ fn internal_ty(ty: &InternalType) -> String {
271
279
}
272
280
}
273
281
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 < ( ) > {
275
286
let Some ( storage_layout) = storage_layout else {
276
287
return Err ( missing_error ( "storage layout" ) ) ;
277
288
} ;
@@ -289,22 +300,29 @@ pub fn print_storage_layout(storage_layout: Option<&StorageLayout>) -> Result<()
289
300
Cell :: new( "Contract" ) ,
290
301
] ;
291
302
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
+ )
305
320
}
306
321
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 < ( ) > {
308
326
let Some ( method_identifiers) = method_identifiers else {
309
327
return Err ( missing_error ( "method identifiers" ) ) ;
310
328
} ;
@@ -315,14 +333,18 @@ fn print_method_identifiers(method_identifiers: &Option<BTreeMap<String, String>
315
333
316
334
let headers = vec ! [ Cell :: new( "Method" ) , Cell :: new( "Identifier" ) ] ;
317
335
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
+ )
323
345
}
324
346
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 < ( ) > {
326
348
if shell:: is_json ( ) {
327
349
return print_json ( map) ;
328
350
}
@@ -332,17 +354,28 @@ fn print_errors_events(map: &Map<String, Value>, is_err: bool) -> Result<()> {
332
354
} else {
333
355
vec ! [ Cell :: new( "Event" ) , Cell :: new( "Topic" ) ]
334
356
} ;
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
+ )
340
366
}
341
367
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 < ( ) > {
343
373
let mut table = Table :: new ( ) ;
344
374
table. apply_modifier ( UTF8_ROUND_CORNERS ) ;
345
375
table. set_header ( headers) ;
376
+ if should_wrap {
377
+ table. set_content_arrangement ( comfy_table:: ContentArrangement :: Dynamic ) ;
378
+ }
346
379
add_rows ( & mut table) ;
347
380
sh_println ! ( "\n {table}\n " ) ?;
348
381
Ok ( ( ) )
0 commit comments