2022-02-21 11:26:41 +02:00
// The "to_cli_args" method of the "interactive-clap" macro is designed to form and print the cli command using the interactive mode for entering parameters.
2022-02-20 21:14:24 +02:00
// 1) build an example: cargo build --example to_cli_args
// 2) go to the `examples` folder: cd target/debug/examples
// 3) run an example: ./to_cli_args (without parameters) => entered interactive mode
// ./to_cli_args send => Your console command: send
// ./to_cli_args display => Your console command: display
// To learn more about the parameters, use "help" flag: ./to_cli_args --help
2022-02-18 16:26:50 +02:00
2022-12-13 17:47:50 +02:00
use inquire ::Select ;
2023-04-02 22:24:06 +03:00
use interactive_clap ::{ ResultFromCli , SelectVariantOrBack , ToCliArgs } ;
2022-02-06 16:01:58 +02:00
use strum ::{ EnumDiscriminants , EnumIter , EnumMessage , IntoEnumIterator } ;
2023-06-02 22:10:37 +02:00
#[ derive(Debug, Clone) ]
pub enum ConnectionConfig {
Testnet ,
Mainnet ,
Betanet ,
}
2022-02-11 11:32:29 +02:00
2023-04-02 22:24:06 +03:00
#[ derive(Debug, Clone, interactive_clap::InteractiveClap) ]
2023-06-02 22:10:37 +02:00
#[ interactive_clap(context = ConnectionConfig) ]
2022-02-06 16:01:58 +02:00
struct OnlineArgs {
2023-04-02 22:24:06 +03:00
/// What is the name of the network
#[ interactive_clap(skip_default_input_arg) ]
network_name : String ,
2022-02-06 16:01:58 +02:00
#[ interactive_clap(subcommand) ]
submit : Submit ,
}
2023-04-02 22:24:06 +03:00
impl OnlineArgs {
2023-06-02 22:10:37 +02:00
fn input_network_name ( _context : & ConnectionConfig ) -> color_eyre ::eyre ::Result < Option < String > > {
2023-04-02 22:24:06 +03:00
match inquire ::Text ::new ( " Input network name " ) . prompt ( ) {
Ok ( value ) = > Ok ( Some ( value ) ) ,
Err (
inquire ::error ::InquireError ::OperationCanceled
| inquire ::error ::InquireError ::OperationInterrupted ,
) = > Ok ( None ) ,
Err ( err ) = > Err ( err . into ( ) ) ,
}
}
}
#[ derive(Debug, EnumDiscriminants, Clone, clap::Parser) ]
2022-02-06 16:01:58 +02:00
#[ strum_discriminants(derive(EnumMessage, EnumIter)) ]
pub enum Submit {
#[ strum_discriminants(strum(message = " I want to send the transaction to the network " )) ]
2023-04-02 22:24:06 +03:00
Send ( Args ) ,
2022-02-06 16:01:58 +02:00
#[ strum_discriminants(strum(
message = " I only want to print base64-encoded transaction for JSON RPC input and exit "
) ) ]
Display ,
}
2023-04-02 22:24:06 +03:00
#[ derive(Debug, EnumDiscriminants, Clone, clap::Parser) ]
pub enum CliSubmit {
Send ( CliArgs ) ,
Display ,
}
impl From < Submit > for CliSubmit {
fn from ( command : Submit ) -> Self {
match command {
Submit ::Send ( args ) = > Self ::Send ( args . into ( ) ) ,
Submit ::Display = > Self ::Display ,
}
}
}
2022-11-20 12:30:48 +01:00
impl interactive_clap ::FromCli for Submit {
2023-06-02 22:10:37 +02:00
type FromCliContext = ConnectionConfig ;
2022-11-20 12:30:48 +01:00
type FromCliError = color_eyre ::eyre ::Error ;
fn from_cli (
optional_clap_variant : Option < < Self as interactive_clap ::ToCli > ::CliVariant > ,
2023-04-02 22:24:06 +03:00
context : Self ::FromCliContext ,
) -> ResultFromCli < < Self as interactive_clap ::ToCli > ::CliVariant , Self ::FromCliError >
2022-12-06 21:08:49 +02:00
where
Self : Sized + interactive_clap ::ToCli ,
{
2023-04-02 22:24:06 +03:00
match optional_clap_variant {
Some ( submit ) = > ResultFromCli ::Ok ( submit ) ,
None = > Self ::choose_variant ( context ) ,
}
}
}
impl interactive_clap ::ToCliArgs for CliSubmit {
fn to_cli_args ( & self ) -> std ::collections ::VecDeque < String > {
match self {
Self ::Send ( cli_args ) = > {
let mut args = cli_args . to_cli_args ( ) ;
args . push_front ( " send " . to_owned ( ) ) ;
args
}
Self ::Display = > {
let mut args = std ::collections ::VecDeque ::new ( ) ;
args . push_front ( " display " . to_owned ( ) ) ;
args
}
2022-11-20 12:30:48 +01:00
}
}
}
2022-02-06 16:01:58 +02:00
impl Submit {
2022-02-11 20:01:46 +02:00
fn choose_variant (
2023-06-02 22:10:37 +02:00
context : ConnectionConfig ,
2023-04-02 22:24:06 +03:00
) -> ResultFromCli <
< Self as interactive_clap ::ToCli > ::CliVariant ,
< Self as interactive_clap ::FromCli > ::FromCliError ,
> {
match Select ::new (
2022-12-13 17:47:50 +02:00
" How would you like to proceed " ,
SubmitDiscriminants ::iter ( )
. map ( SelectVariantOrBack ::Variant )
. chain ( [ SelectVariantOrBack ::Back ] )
. collect ( ) ,
)
. prompt ( )
2023-04-02 22:24:06 +03:00
{
Ok ( SelectVariantOrBack ::Variant ( variant ) ) = > ResultFromCli ::Ok ( match variant {
SubmitDiscriminants ::Send = > {
let cli_args =
match < Args as interactive_clap ::FromCli > ::from_cli ( None , context ) {
ResultFromCli ::Ok ( cli_args ) = > cli_args ,
ResultFromCli ::Cancel ( optional_cli_args ) = > {
return ResultFromCli ::Cancel ( Some ( CliSubmit ::Send (
optional_cli_args . unwrap_or_default ( ) ,
) ) ) ;
}
ResultFromCli ::Back = > return ResultFromCli ::Back ,
ResultFromCli ::Err ( optional_cli_args , err ) = > {
return ResultFromCli ::Err (
Some ( CliSubmit ::Send ( optional_cli_args . unwrap_or_default ( ) ) ) ,
err ,
) ;
}
} ;
CliSubmit ::Send ( cli_args )
}
SubmitDiscriminants ::Display = > CliSubmit ::Display ,
} ) ,
Ok ( SelectVariantOrBack ::Back ) = > ResultFromCli ::Back ,
Err (
inquire ::error ::InquireError ::OperationCanceled
| inquire ::error ::InquireError ::OperationInterrupted ,
) = > ResultFromCli ::Cancel ( None ) ,
Err ( err ) = > ResultFromCli ::Err ( None , err . into ( ) ) ,
2022-02-06 16:01:58 +02:00
}
}
}
impl interactive_clap ::ToCli for Submit {
2023-04-02 22:24:06 +03:00
type CliVariant = CliSubmit ;
2022-02-06 16:01:58 +02:00
}
2022-12-13 17:47:50 +02:00
impl std ::fmt ::Display for SubmitDiscriminants {
fn fmt ( & self , f : & mut std ::fmt ::Formatter ) -> std ::fmt ::Result {
match self {
Self ::Send = > write! ( f , " send " ) ,
Self ::Display = > write! ( f , " display " ) ,
}
}
}
2023-04-02 22:24:06 +03:00
#[ derive(Debug, Clone, interactive_clap::InteractiveClap, clap::Args) ]
2023-06-02 22:10:37 +02:00
#[ interactive_clap(context = ConnectionConfig) ]
2023-04-02 22:24:06 +03:00
pub struct Args {
age : u64 ,
first_name : String ,
second_name : String ,
}
fn main ( ) -> color_eyre ::Result < ( ) > {
2022-02-11 11:32:29 +02:00
let mut cli_online_args = OnlineArgs ::parse ( ) ;
2023-06-02 22:10:37 +02:00
let context = ConnectionConfig ::Testnet ; //#[interactive_clap(context = ConnectionConfig)]
2023-04-02 22:24:06 +03:00
let cli_args = loop {
match < OnlineArgs as interactive_clap ::FromCli > ::from_cli (
Some ( cli_online_args ) ,
2022-12-06 21:08:49 +02:00
context . clone ( ) ,
2023-04-02 22:24:06 +03:00
) {
ResultFromCli ::Ok ( cli_args ) = > break cli_args ,
ResultFromCli ::Cancel ( Some ( cli_args ) ) = > {
println! (
" Your console command: {} " ,
2025-01-07 20:32:49 +02:00
shell_words ::join ( cli_args . to_cli_args ( ) )
2023-04-02 22:24:06 +03:00
) ;
return Ok ( ( ) ) ;
}
ResultFromCli ::Cancel ( None ) = > {
println! ( " Goodbye! " ) ;
return Ok ( ( ) ) ;
}
ResultFromCli ::Back = > {
cli_online_args = Default ::default ( ) ;
}
ResultFromCli ::Err ( cli_args , err ) = > {
if let Some ( cli_args ) = cli_args {
println! (
" Your console command: {} " ,
2025-01-07 20:32:49 +02:00
shell_words ::join ( cli_args . to_cli_args ( ) )
2023-04-02 22:24:06 +03:00
) ;
}
return Err ( err ) ;
}
2022-08-31 12:29:24 +03:00
}
} ;
2023-04-02 22:24:06 +03:00
println! ( " cli_args: {:?} " , cli_args ) ;
2022-02-11 11:32:29 +02:00
println! (
2022-02-18 16:26:50 +02:00
" Your console command: {} " ,
2025-01-07 20:32:49 +02:00
shell_words ::join ( cli_args . to_cli_args ( ) )
2022-02-11 11:32:29 +02:00
) ;
2023-04-02 22:24:06 +03:00
Ok ( ( ) )
2022-02-06 16:01:58 +02:00
}