1- use std:: { io:: { BufReader , self , BufRead , BufWriter , Write } , fs, collections:: HashMap } ;
21use ethabi:: ParamType ;
32use hex:: ToHex ;
43use serde:: Serialize ;
4+ use std:: {
5+ collections:: HashMap ,
6+ fs,
7+ io:: { self , BufRead , BufReader , BufWriter , Write } ,
8+ path:: PathBuf ,
9+ } ;
510
6- use tinytemplate:: { TinyTemplate , format_unescaped} ;
711use clap:: Parser ;
812use convert_case:: { Case , Casing } ;
913use itertools:: Itertools ;
1014use sha3:: { Digest , Keccak256 } ;
15+ use snafu:: prelude:: * ;
16+ use tinytemplate:: { format_unescaped, TinyTemplate } ;
1117
1218#[ derive( Parser , Debug ) ]
1319struct Args {
@@ -377,7 +383,8 @@ fn convert_type(ty: &ParamType) -> String {
377383 128 => "i128" ,
378384
379385 _ => "I256" ,
380- } . to_owned ( ) ,
386+ }
387+ . to_owned ( ) ,
381388
382389 ParamType :: Uint ( size) => match size {
383390 8 => "u8" ,
@@ -387,20 +394,34 @@ fn convert_type(ty: &ParamType) -> String {
387394 128 => "u128" ,
388395
389396 _ => "U256" ,
390- } . to_owned ( ) ,
397+ }
398+ . to_owned ( ) ,
391399 }
392400}
393401
402+ #[ derive( Debug , Snafu ) ]
403+ enum Error {
404+ #[ snafu( display( "Unable to open input file {}: {}" , path. display( ) , source) ) ]
405+ ReadInput { source : io:: Error , path : PathBuf } ,
406+
407+ #[ snafu( display( "Unable to create output file {}: {}" , path. display( ) , source) ) ]
408+ WriteOutput { source : io:: Error , path : PathBuf } ,
409+ }
410+
394411fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
395412 let args = Args :: parse ( ) ;
396413
397414 let mut reader: Box < dyn BufRead > = match args. input {
398- Some ( filename) => Box :: new ( BufReader :: new ( fs:: File :: open ( filename) ?) ) ,
415+ Some ( filename) => Box :: new ( BufReader :: new (
416+ fs:: File :: open ( filename. clone ( ) ) . context ( ReadInputSnafu { path : filename } ) ?,
417+ ) ) ,
399418 None => Box :: new ( BufReader :: new ( io:: stdin ( ) ) ) ,
400419 } ;
401420
402421 let mut writer: Box < dyn Write > = match args. output {
403- Some ( filename) => Box :: new ( BufWriter :: new ( fs:: File :: create ( filename) ?) ) ,
422+ Some ( filename) => Box :: new ( BufWriter :: new (
423+ fs:: File :: create ( filename. clone ( ) ) . context ( WriteOutputSnafu { path : filename } ) ?,
424+ ) ) ,
404425 None => Box :: new ( BufWriter :: new ( io:: stdout ( ) ) ) ,
405426 } ;
406427
@@ -415,18 +436,33 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
415436 template. add_template ( "module" , MODULE_TEMPLATE ) ?;
416437
417438 template. add_formatter ( "snake" , |value, buf| match value {
418- serde_json:: Value :: String ( s) => { * buf += & s. to_case ( Case :: Snake ) ; Ok ( ( ) ) } ,
419- _ => Err ( tinytemplate:: error:: Error :: GenericError { msg : "string value expected" . to_owned ( ) } ) ,
439+ serde_json:: Value :: String ( s) => {
440+ * buf += & s. to_case ( Case :: Snake ) ;
441+ Ok ( ( ) )
442+ }
443+ _ => Err ( tinytemplate:: error:: Error :: GenericError {
444+ msg : "string value expected" . to_owned ( ) ,
445+ } ) ,
420446 } ) ;
421447
422448 template. add_formatter ( "upper_snake" , |value, buf| match value {
423- serde_json:: Value :: String ( s) => { * buf += & s. to_case ( Case :: UpperSnake ) ; Ok ( ( ) ) } ,
424- _ => Err ( tinytemplate:: error:: Error :: GenericError { msg : "string value expected" . to_owned ( ) } ) ,
449+ serde_json:: Value :: String ( s) => {
450+ * buf += & s. to_case ( Case :: UpperSnake ) ;
451+ Ok ( ( ) )
452+ }
453+ _ => Err ( tinytemplate:: error:: Error :: GenericError {
454+ msg : "string value expected" . to_owned ( ) ,
455+ } ) ,
425456 } ) ;
426457
427458 template. add_formatter ( "upper_camel" , |value, buf| match value {
428- serde_json:: Value :: String ( s) => { * buf += & s. to_case ( Case :: UpperCamel ) ; Ok ( ( ) ) } ,
429- _ => Err ( tinytemplate:: error:: Error :: GenericError { msg : "string value expected" . to_owned ( ) } ) ,
459+ serde_json:: Value :: String ( s) => {
460+ * buf += & s. to_case ( Case :: UpperCamel ) ;
461+ Ok ( ( ) )
462+ }
463+ _ => Err ( tinytemplate:: error:: Error :: GenericError {
464+ msg : "string value expected" . to_owned ( ) ,
465+ } ) ,
430466 } ) ;
431467
432468 template. add_formatter ( "capitalize" , |value, buf| match value {
@@ -437,8 +473,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
437473 * buf += tail;
438474
439475 Ok ( ( ) )
440- } ,
441- _ => Err ( tinytemplate:: error:: Error :: GenericError { msg : "string value expected" . to_owned ( ) } ) ,
476+ }
477+ _ => Err ( tinytemplate:: error:: Error :: GenericError {
478+ msg : "string value expected" . to_owned ( ) ,
479+ } ) ,
442480 } ) ;
443481
444482 template. add_formatter ( "ordinal" , |value, buf| match value {
@@ -456,9 +494,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
456494 buf. push_str ( ordinal) ;
457495
458496 Ok ( ( ) )
459- } ,
497+ }
460498
461- _ => Err ( tinytemplate:: error:: Error :: GenericError { msg : "string value expected" . to_owned ( ) } ) ,
499+ _ => Err ( tinytemplate:: error:: Error :: GenericError {
500+ msg : "string value expected" . to_owned ( ) ,
501+ } ) ,
462502 } ) ;
463503
464504 template. add_formatter ( "convert_type" , |value, buf| match value {
@@ -468,18 +508,24 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
468508
469509 buf. push_str ( & converted) ;
470510 Ok ( ( ) )
471- } ,
511+ }
472512
473- _ => Err ( tinytemplate:: error:: Error :: GenericError { msg : "string value expected" . to_owned ( ) } ) ,
513+ _ => Err ( tinytemplate:: error:: Error :: GenericError {
514+ msg : "string value expected" . to_owned ( ) ,
515+ } ) ,
474516 } ) ;
475517
476518 let mut is_overloaded = HashMap :: new ( ) ;
477519
478520 for function in parsed
479521 . members ( )
480- . filter ( |item| item[ "type" ] == "function" )
481- . filter ( |item| item[ "stateMutability" ] != "view" )
482- . filter ( |item| item[ "outputs" ] . members ( ) . all ( |output| output[ "type" ] == "bool" ) )
522+ . filter ( |item| item[ "type" ] == "function" )
523+ . filter ( |item| item[ "stateMutability" ] != "view" )
524+ . filter ( |item| {
525+ item[ "outputs" ]
526+ . members ( )
527+ . all ( |output| output[ "type" ] == "bool" )
528+ } )
483529 {
484530 let function_name = function[ "name" ] . as_str ( ) . unwrap ( ) ;
485531
@@ -494,27 +540,35 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
494540
495541 for function in parsed
496542 . members ( )
497- . filter ( |item| item[ "type" ] == "function" )
498- . filter ( |item| item[ "stateMutability" ] != "view" )
499- . filter ( |item| item[ "outputs" ] . members ( ) . all ( |output| output[ "type" ] == "bool" ) )
543+ . filter ( |item| item[ "type" ] == "function" )
544+ . filter ( |item| item[ "stateMutability" ] != "view" )
545+ . filter ( |item| {
546+ item[ "outputs" ]
547+ . members ( )
548+ . all ( |output| output[ "type" ] == "bool" )
549+ } )
500550 {
501551 let function_name = function[ "name" ] . to_string ( ) ;
502552
503- let inputs: Vec < _ > = function[ "inputs" ] . members ( ) . map ( |m| {
504- let raw_type = m[ "type" ] . as_str ( ) . unwrap ( ) ;
505- let param_type = ethabi:: param_type:: Reader :: read ( raw_type) . unwrap ( ) ;
506- let converted = convert_type ( & param_type) ;
507-
508- Input {
509- name : m[ "name" ] . to_string ( ) ,
510- evm_type : raw_type. to_string ( ) ,
511- rust_type : converted,
512- }
513- } ) . collect ( ) ;
553+ let inputs: Vec < _ > = function[ "inputs" ]
554+ . members ( )
555+ . map ( |m| {
556+ let raw_type = m[ "type" ] . as_str ( ) . unwrap ( ) ;
557+ let param_type = ethabi:: param_type:: Reader :: read ( raw_type) . unwrap ( ) ;
558+ let converted = convert_type ( & param_type) ;
559+
560+ Input {
561+ name : m[ "name" ] . to_string ( ) ,
562+ evm_type : raw_type. to_string ( ) ,
563+ rust_type : converted,
564+ }
565+ } )
566+ . collect ( ) ;
514567
515568 // let outputs: String = function["outputs"].members().map(|m| format!("{}: {}, ", m["name"], m["type"])).collect();
516569
517- let selector = format ! ( "{name}({args})" ,
570+ let selector = format ! (
571+ "{name}({args})" ,
518572 name = function_name,
519573 args = inputs. iter( ) . map( |input| input. evm_type. as_str( ) ) . join( "," ) ,
520574 ) ;
@@ -526,12 +580,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
526580
527581 if is_overloaded[ function_name. as_str ( ) ] {
528582 let function = {
529- if let Some ( function) = overloaded_functions. iter_mut ( ) . find ( |f| f. name == function_name) {
583+ if let Some ( function) = overloaded_functions
584+ . iter_mut ( )
585+ . find ( |f| f. name == function_name)
586+ {
530587 function
531588 } else {
532- overloaded_functions. push ( OverloadedFunction {
589+ overloaded_functions. push ( OverloadedFunction {
533590 name : function_name. clone ( ) ,
534- variants : Vec :: new ( )
591+ variants : Vec :: new ( ) ,
535592 } ) ;
536593
537594 overloaded_functions. last_mut ( ) . unwrap ( )
@@ -542,7 +599,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
542599 inputs,
543600 output : "bool" . to_owned ( ) , // TODO
544601 selector,
545- selector_hash : selector_hash. encode_hex ( )
602+ selector_hash : selector_hash. encode_hex ( ) ,
546603 } )
547604 } else {
548605 functions. push ( Function {
0 commit comments