draft: Result to ResultFromCli

This commit is contained in:
FroVolod
2023-03-01 22:32:39 +02:00
parent 95d20ca7b5
commit 54b154b0f8
4 changed files with 121 additions and 22 deletions

View File

@@ -10,19 +10,69 @@
use inquire::Select;
use strum::{EnumDiscriminants, EnumIter, EnumMessage, IntoEnumIterator};
use interactive_clap::{SelectVariantOrBack, ToCliArgs};
use interactive_clap::{ResultFromCli, SelectVariantOrBack, ToCliArgs};
mod common;
#[derive(Debug, Clone, interactive_clap_derive::InteractiveClap)]
#[interactive_clap(context = common::ConnectionConfig)]
#[interactive_clap(skip_default_from_cli)]
struct OnlineArgs {
/// What is the name of the network
// #[interactive_clap(skip_default_input_arg)]
network_name: String,
#[interactive_clap(subcommand)]
submit: Submit,
}
#[derive(Debug, EnumDiscriminants, Clone, clap::Parser, interactive_clap_derive::ToCliArgs)]
impl interactive_clap::FromCli for OnlineArgs {
type FromCliContext = common::ConnectionConfig;
type FromCliError = color_eyre::eyre::Error;
fn from_cli(
optional_clap_variant: Option<<Self as interactive_clap::ToCli>::CliVariant>,
context: Self::FromCliContext,
) -> ResultFromCli<<Self as interactive_clap::ToCli>::CliVariant, Self::FromCliError>
where
Self: Sized + interactive_clap::ToCli,
{
let optional_network_name = match optional_clap_variant
.clone()
.and_then(|clap_variant| clap_variant.network_name)
{
Some(network_name) => Some(network_name),
None => match Self::input_network_name(&context) {
Ok(network_name) => Some(network_name),
Err(_) => {
return ResultFromCli::Exit;
}
},
};
let optional_submit =
match optional_clap_variant.and_then(|clap_variant| clap_variant.submit) {
Some(submit) => Some(submit),
None => match Submit::choose_variant(context) {
Ok(Some(submit)) => Some(submit.into()),
Ok(None) => {
return ResultFromCli::Back;
}
Err(_) => {
return ResultFromCli::Exit;
}
},
};
ResultFromCli::Ok(CliOnlineArgs {
network_name: optional_network_name,
submit: optional_submit,
})
}
}
#[derive(Debug, EnumDiscriminants, Clone, clap::Parser)]
#[strum_discriminants(derive(EnumMessage, EnumIter))]
// #[interactive_clap(context = common::ConnectionConfig)]
// #[interactive_clap(skip_default_from_cli)]
pub enum Submit {
#[strum_discriminants(strum(message = "I want to send the transaction to the network"))]
Send,
@@ -32,21 +82,56 @@ pub enum Submit {
Display,
}
#[derive(Debug, EnumDiscriminants, Clone, clap::Parser)]
pub enum CliSubmit {
Send,
Display,
}
impl From<Submit> for CliSubmit {
fn from(command: Submit) -> Self {
match command {
Submit::Send => Self::Send,
Submit::Display => Self::Display,
}
}
}
impl interactive_clap::FromCli for Submit {
type FromCliContext = common::ConnectionConfig;
type FromCliError = color_eyre::eyre::Error;
fn from_cli(
optional_clap_variant: Option<<Self as interactive_clap::ToCli>::CliVariant>,
_context: Self::FromCliContext,
) -> Result<Option<Self>, Self::FromCliError>
context: Self::FromCliContext,
) -> ResultFromCli<<Self as interactive_clap::ToCli>::CliVariant, Self::FromCliError>
where
Self: Sized + interactive_clap::ToCli,
{
let submit: Option<Submit> = optional_clap_variant.clone();
match submit {
Some(submit) => Ok(Some(submit)),
None => Ok(Some(Submit::Display)),
match optional_clap_variant {
Some(submit) => ResultFromCli::Ok(submit),
None => match Self::choose_variant(context) {
Ok(Some(submit)) => ResultFromCli::Ok(submit.into()),
Ok(None) => ResultFromCli::Back,
Err(_) => ResultFromCli::Exit,
},
}
}
}
impl interactive_clap::ToCliArgs for CliSubmit {
fn to_cli_args(&self) -> std::collections::VecDeque<String> {
match self {
Self::Send => {
let mut args = std::collections::VecDeque::new();
args.push_front("send".to_owned());
args
}
Self::Display => {
let mut args = std::collections::VecDeque::new();
args.push_front("display".to_owned());
args
}
}
}
}
@@ -71,9 +156,8 @@ impl Submit {
}
}
}
impl interactive_clap::ToCli for Submit {
type CliVariant = Submit;
type CliVariant = CliSubmit;
}
impl std::fmt::Display for SubmitDiscriminants {
@@ -89,13 +173,14 @@ fn main() {
let mut cli_online_args = OnlineArgs::parse();
let context = common::ConnectionConfig::Testnet; //#[interactive_clap(context = common::ConnectionConfig)]
let online_args = loop {
if let Some(args) = <OnlineArgs as interactive_clap::FromCli>::from_cli(
match <OnlineArgs as interactive_clap::FromCli>::from_cli(
Some(cli_online_args.clone()),
context.clone(),
)
.unwrap()
{
break args;
) {
ResultFromCli::Ok(args) => break args,
ResultFromCli::Back => (),
ResultFromCli::Exit => todo!(),
ResultFromCli::Err(cli_args, err) => todo!(),
}
};
cli_online_args = online_args.into();

View File

@@ -73,7 +73,7 @@ pub fn from_cli_for_enum(
fn from_cli(
optional_clap_variant: Option<<Self as interactive_clap::ToCli>::CliVariant>,
context: Self::FromCliContext,
) -> Result<Option<Self>, Self::FromCliError> where Self: Sized + interactive_clap::ToCli {
) -> ResultFromCli<<Self as ToCli>::CliVariant, Self::FromCliError> where Self: Sized + interactive_clap::ToCli {
match optional_clap_variant {
#(#from_cli_variants)*
None => Self::choose_variant(context.clone()),

View File

@@ -84,7 +84,7 @@ pub fn from_cli_for_struct(
fn from_cli(
optional_clap_variant: Option<<Self as interactive_clap::ToCli>::CliVariant>,
context: Self::FromCliContext,
) -> Result<Option<Self>, Self::FromCliError> where Self: Sized + interactive_clap::ToCli {
) -> ResultFromCli<<Self as ToCli>::CliVariant, Self::FromCliError> where Self: Sized + interactive_clap::ToCli {
#(#fields_value)*
#new_context_scope
#field_value_named_arg
@@ -100,12 +100,15 @@ fn fields_value(field: &syn::Field) -> proc_macro2::TokenStream {
let fn_from_cli_arg = syn::Ident::new(&format!("from_cli_{}", &ident_field), Span::call_site());
if super::fields_without_subcommand::is_field_without_subcommand(field) {
quote! {
let #ident_field = Self::#fn_from_cli_arg(
let #ident_field = match Self::#fn_from_cli_arg(
optional_clap_variant
.clone()
.and_then(|clap_variant| clap_variant.#ident_field),
&context,
)?;
) {
Ok(#ident_field) => #ident_field,
Err(err) => return ResultFromCli::Err(color_eyre::Report::msg(err.to_string()));
};
}
} else {
quote!()
@@ -148,9 +151,12 @@ fn field_value_named_arg(
Some(output_context_dir) => {
let context_for_struct = syn::Ident::new(&format!("{}Context", &name), Span::call_site());
quote! {
let new_context = #context_for_struct::from_previous_context(context, &new_context_scope)?;
let new_context = match #context_for_struct::from_previous_context(context, &new_context_scope) {
Ok(new_context) => new_context,
Err(err) => return ResultFromCli::Err(color_eyre::Report::msg(err.to_string()));
};
let output_context = #output_context_dir::from(new_context);
let #ident_field = <#ty as interactive_clap::FromCli>::from_cli(
let #ident_field = match <#ty as interactive_clap::FromCli>::from_cli(
optional_clap_variant.and_then(|clap_variant| match clap_variant.#ident_field {
Some(#enum_for_clap_named_arg::#variant_name(cli_arg)) => Some(cli_arg),
None => None,

View File

@@ -30,13 +30,21 @@ pub trait ToCliArgs {
fn to_cli_args(&self) -> std::collections::VecDeque<String>;
}
pub enum ResultFromCli<T, E> {
Ok(T),
Back,
Exit,
Err(T, E),
}
pub trait FromCli {
type FromCliContext;
type FromCliError;
fn from_cli(
optional_clap_variant: Option<<Self as ToCli>::CliVariant>,
context: Self::FromCliContext,
) -> Result<Option<Self>, Self::FromCliError>
) -> ResultFromCli<<Self as ToCli>::CliVariant, Self::FromCliError>
where
Self: Sized + ToCli;
}