mirror of
https://github.com/Drop-OSS/interactive-clap.git
synced 2026-01-30 20:55:25 +01:00
draft: Result to ResultFromCli
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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,
|
||||
|
||||
10
src/lib.rs
10
src/lib.rs
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user