@@ -40,11 +40,14 @@ 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
+ #[ arg( long, short, help_heading = "Display options" ) ]
45
+ pub wrap : bool ,
43
46
}
44
47
45
48
impl InspectArgs {
46
49
pub fn run ( self ) -> Result < ( ) > {
47
- let Self { contract, field, build, strip_yul_comments } = self ;
50
+ let Self { contract, field, build, strip_yul_comments, wrap } = self ;
48
51
49
52
trace ! ( target: "forge" , ?field, ?contract, "running forge inspect" ) ;
50
53
@@ -86,7 +89,7 @@ impl InspectArgs {
86
89
. abi
87
90
. as_ref ( )
88
91
. ok_or_else ( || eyre:: eyre!( "Failed to fetch lossless ABI" ) ) ?;
89
- print_abi ( abi) ?;
92
+ print_abi ( abi, wrap ) ?;
90
93
}
91
94
ContractArtifactField :: Bytecode => {
92
95
print_json_str ( & artifact. bytecode , Some ( "object" ) ) ?;
@@ -101,13 +104,13 @@ impl InspectArgs {
101
104
print_json_str ( & artifact. legacy_assembly , None ) ?;
102
105
}
103
106
ContractArtifactField :: MethodIdentifiers => {
104
- print_method_identifiers ( & artifact. method_identifiers ) ?;
107
+ print_method_identifiers ( & artifact. method_identifiers , wrap ) ?;
105
108
}
106
109
ContractArtifactField :: GasEstimates => {
107
110
print_json ( & artifact. gas_estimates ) ?;
108
111
}
109
112
ContractArtifactField :: StorageLayout => {
110
- print_storage_layout ( artifact. storage_layout . as_ref ( ) ) ?;
113
+ print_storage_layout ( artifact. storage_layout . as_ref ( ) , wrap ) ?;
111
114
}
112
115
ContractArtifactField :: DevDoc => {
113
116
print_json ( & artifact. devdoc ) ?;
@@ -129,11 +132,11 @@ impl InspectArgs {
129
132
}
130
133
ContractArtifactField :: Errors => {
131
134
let out = artifact. abi . as_ref ( ) . map_or ( Map :: new ( ) , parse_errors) ;
132
- print_errors_events ( & out, true ) ?;
135
+ print_errors_events ( & out, true , wrap ) ?;
133
136
}
134
137
ContractArtifactField :: Events => {
135
138
let out = artifact. abi . as_ref ( ) . map_or ( Map :: new ( ) , parse_events) ;
136
- print_errors_events ( & out, false ) ?;
139
+ print_errors_events ( & out, false , wrap ) ?;
137
140
}
138
141
ContractArtifactField :: StandardJson => {
139
142
let standard_json = if let Some ( version) = solc_version {
@@ -187,66 +190,70 @@ fn parse_event_params(ev_params: &[EventParam]) -> String {
187
190
. join ( "," )
188
191
}
189
192
190
- fn print_abi ( abi : & JsonAbi ) -> Result < ( ) > {
193
+ fn print_abi ( abi : & JsonAbi , should_wrap : bool ) -> Result < ( ) > {
191
194
if shell:: is_json ( ) {
192
195
return print_json ( abi)
193
196
}
194
197
195
198
let headers = vec ! [ Cell :: new( "Type" ) , Cell :: new( "Signature" ) , Cell :: new( "Selector" ) ] ;
196
- print_table ( headers, |table| {
197
- // Print events
198
- for ev in abi. events . iter ( ) . flat_map ( |( _, events) | events) {
199
- let types = parse_event_params ( & ev. inputs ) ;
200
- let selector = ev. selector ( ) . to_string ( ) ;
201
- table. add_row ( [ "event" , & format ! ( "{}({})" , ev. name, types) , & selector] ) ;
202
- }
199
+ print_table (
200
+ headers,
201
+ |table| {
202
+ // Print events
203
+ for ev in abi. events . iter ( ) . flat_map ( |( _, events) | events) {
204
+ let types = parse_event_params ( & ev. inputs ) ;
205
+ let selector = ev. selector ( ) . to_string ( ) ;
206
+ table. add_row ( [ "event" , & format ! ( "{}({})" , ev. name, types) , & selector] ) ;
207
+ }
203
208
204
- // Print errors
205
- for er in abi. errors . iter ( ) . flat_map ( |( _, errors) | errors) {
206
- let selector = er. selector ( ) . to_string ( ) ;
207
- table. add_row ( [
208
- "error" ,
209
- & format ! ( "{}({})" , er. name, get_ty_sig( & er. inputs) ) ,
210
- & selector,
211
- ] ) ;
212
- }
209
+ // Print errors
210
+ for er in abi. errors . iter ( ) . flat_map ( |( _, errors) | errors) {
211
+ let selector = er. selector ( ) . to_string ( ) ;
212
+ table. add_row ( [
213
+ "error" ,
214
+ & format ! ( "{}({})" , er. name, get_ty_sig( & er. inputs) ) ,
215
+ & selector,
216
+ ] ) ;
217
+ }
213
218
214
- // Print functions
215
- for func in abi. functions . iter ( ) . flat_map ( |( _, f) | f) {
216
- let selector = func. selector ( ) . to_string ( ) ;
217
- let state_mut = func. state_mutability . as_json_str ( ) ;
218
- let func_sig = if !func. outputs . is_empty ( ) {
219
- format ! (
220
- "{}({}) {state_mut} returns ({})" ,
221
- func. name,
222
- get_ty_sig( & func. inputs) ,
223
- get_ty_sig( & func. outputs)
224
- )
225
- } else {
226
- format ! ( "{}({}) {state_mut}" , func. name, get_ty_sig( & func. inputs) )
227
- } ;
228
- table. add_row ( [ "function" , & func_sig, & selector] ) ;
229
- }
219
+ // Print functions
220
+ for func in abi. functions . iter ( ) . flat_map ( |( _, f) | f) {
221
+ let selector = func. selector ( ) . to_string ( ) ;
222
+ let state_mut = func. state_mutability . as_json_str ( ) ;
223
+ let func_sig = if !func. outputs . is_empty ( ) {
224
+ format ! (
225
+ "{}({}) {state_mut} returns ({})" ,
226
+ func. name,
227
+ get_ty_sig( & func. inputs) ,
228
+ get_ty_sig( & func. outputs)
229
+ )
230
+ } else {
231
+ format ! ( "{}({}) {state_mut}" , func. name, get_ty_sig( & func. inputs) )
232
+ } ;
233
+ table. add_row ( [ "function" , & func_sig, & selector] ) ;
234
+ }
230
235
231
- if let Some ( constructor) = abi. constructor ( ) {
232
- let state_mut = constructor. state_mutability . as_json_str ( ) ;
233
- table. add_row ( [
234
- "constructor" ,
235
- & format ! ( "constructor({}) {state_mut}" , get_ty_sig( & constructor. inputs) ) ,
236
- "" ,
237
- ] ) ;
238
- }
236
+ if let Some ( constructor) = abi. constructor ( ) {
237
+ let state_mut = constructor. state_mutability . as_json_str ( ) ;
238
+ table. add_row ( [
239
+ "constructor" ,
240
+ & format ! ( "constructor({}) {state_mut}" , get_ty_sig( & constructor. inputs) ) ,
241
+ "" ,
242
+ ] ) ;
243
+ }
239
244
240
- if let Some ( fallback) = & abi. fallback {
241
- let state_mut = fallback. state_mutability . as_json_str ( ) ;
242
- table. add_row ( [ "fallback" , & format ! ( "fallback() {state_mut}" ) , "" ] ) ;
243
- }
245
+ if let Some ( fallback) = & abi. fallback {
246
+ let state_mut = fallback. state_mutability . as_json_str ( ) ;
247
+ table. add_row ( [ "fallback" , & format ! ( "fallback() {state_mut}" ) , "" ] ) ;
248
+ }
244
249
245
- if let Some ( receive) = & abi. receive {
246
- let state_mut = receive. state_mutability . as_json_str ( ) ;
247
- table. add_row ( [ "receive" , & format ! ( "receive() {state_mut}" ) , "" ] ) ;
248
- }
249
- } )
250
+ if let Some ( receive) = & abi. receive {
251
+ let state_mut = receive. state_mutability . as_json_str ( ) ;
252
+ table. add_row ( [ "receive" , & format ! ( "receive() {state_mut}" ) , "" ] ) ;
253
+ }
254
+ } ,
255
+ should_wrap,
256
+ )
250
257
}
251
258
252
259
fn get_ty_sig ( inputs : & [ Param ] ) -> String {
@@ -274,7 +281,10 @@ fn internal_ty(ty: &InternalType) -> String {
274
281
}
275
282
}
276
283
277
- pub fn print_storage_layout ( storage_layout : Option < & StorageLayout > ) -> Result < ( ) > {
284
+ pub fn print_storage_layout (
285
+ storage_layout : Option < & StorageLayout > ,
286
+ should_wrap : bool ,
287
+ ) -> Result < ( ) > {
278
288
let Some ( storage_layout) = storage_layout else {
279
289
eyre:: bail!( "Could not get storage layout" ) ;
280
290
} ;
@@ -292,22 +302,29 @@ pub fn print_storage_layout(storage_layout: Option<&StorageLayout>) -> Result<()
292
302
Cell :: new( "Contract" ) ,
293
303
] ;
294
304
295
- print_table ( headers, |table| {
296
- for slot in & storage_layout. storage {
297
- let storage_type = storage_layout. types . get ( & slot. storage_type ) ;
298
- table. add_row ( [
299
- slot. label . as_str ( ) ,
300
- storage_type. map_or ( "?" , |t| & t. label ) ,
301
- & slot. slot ,
302
- & slot. offset . to_string ( ) ,
303
- storage_type. map_or ( "?" , |t| & t. number_of_bytes ) ,
304
- & slot. contract ,
305
- ] ) ;
306
- }
307
- } )
305
+ print_table (
306
+ headers,
307
+ |table| {
308
+ for slot in & storage_layout. storage {
309
+ let storage_type = storage_layout. types . get ( & slot. storage_type ) ;
310
+ table. add_row ( [
311
+ slot. label . as_str ( ) ,
312
+ storage_type. map_or ( "?" , |t| & t. label ) ,
313
+ & slot. slot ,
314
+ & slot. offset . to_string ( ) ,
315
+ storage_type. map_or ( "?" , |t| & t. number_of_bytes ) ,
316
+ & slot. contract ,
317
+ ] ) ;
318
+ }
319
+ } ,
320
+ should_wrap,
321
+ )
308
322
}
309
323
310
- fn print_method_identifiers ( method_identifiers : & Option < BTreeMap < String , String > > ) -> Result < ( ) > {
324
+ fn print_method_identifiers (
325
+ method_identifiers : & Option < BTreeMap < String , String > > ,
326
+ should_wrap : bool ,
327
+ ) -> Result < ( ) > {
311
328
let Some ( method_identifiers) = method_identifiers else {
312
329
eyre:: bail!( "Could not get method identifiers" ) ;
313
330
} ;
@@ -318,14 +335,18 @@ fn print_method_identifiers(method_identifiers: &Option<BTreeMap<String, String>
318
335
319
336
let headers = vec ! [ Cell :: new( "Method" ) , Cell :: new( "Identifier" ) ] ;
320
337
321
- print_table ( headers, |table| {
322
- for ( method, identifier) in method_identifiers {
323
- table. add_row ( [ method, identifier] ) ;
324
- }
325
- } )
338
+ print_table (
339
+ headers,
340
+ |table| {
341
+ for ( method, identifier) in method_identifiers {
342
+ table. add_row ( [ method, identifier] ) ;
343
+ }
344
+ } ,
345
+ should_wrap,
346
+ )
326
347
}
327
348
328
- fn print_errors_events ( map : & Map < String , Value > , is_err : bool ) -> Result < ( ) > {
349
+ fn print_errors_events ( map : & Map < String , Value > , is_err : bool , should_wrap : bool ) -> Result < ( ) > {
329
350
if shell:: is_json ( ) {
330
351
return print_json ( map) ;
331
352
}
@@ -335,17 +356,28 @@ fn print_errors_events(map: &Map<String, Value>, is_err: bool) -> Result<()> {
335
356
} else {
336
357
vec ! [ Cell :: new( "Event" ) , Cell :: new( "Topic" ) ]
337
358
} ;
338
- print_table ( headers, |table| {
339
- for ( method, selector) in map {
340
- table. add_row ( [ method, selector. as_str ( ) . unwrap ( ) ] ) ;
341
- }
342
- } )
359
+ print_table (
360
+ headers,
361
+ |table| {
362
+ for ( method, selector) in map {
363
+ table. add_row ( [ method, selector. as_str ( ) . unwrap ( ) ] ) ;
364
+ }
365
+ } ,
366
+ should_wrap,
367
+ )
343
368
}
344
369
345
- fn print_table ( headers : Vec < Cell > , add_rows : impl FnOnce ( & mut Table ) ) -> Result < ( ) > {
370
+ fn print_table (
371
+ headers : Vec < Cell > ,
372
+ add_rows : impl FnOnce ( & mut Table ) ,
373
+ should_wrap : bool ,
374
+ ) -> Result < ( ) > {
346
375
let mut table = Table :: new ( ) ;
347
376
table. apply_modifier ( UTF8_ROUND_CORNERS ) ;
348
377
table. set_header ( headers) ;
378
+ if should_wrap {
379
+ table. set_content_arrangement ( comfy_table:: ContentArrangement :: Dynamic ) ;
380
+ }
349
381
add_rows ( & mut table) ;
350
382
sh_println ! ( "\n {table}\n " ) ?;
351
383
Ok ( ( ) )
0 commit comments