interactive_clap/
lib.rs

1//! The Interactive-clap library is an add-on for the Command Line Argument
2//! Parser ([`CLAP`](https://crates.io/crates/clap>)). Interactive-clap allows you to parse
3//! command line options. The peculiarity of this macro is that in the absence
4//! of command line parameters, the interactive mode of entering these data by
5//! the user is activated.
6
7pub use interactive_clap_derive::{InteractiveClap, ToCliArgs};
8
9/// Associated type [`Self::CliVariant`] is defined during derive of
10/// [`macro@crate::InteractiveClap`]
11///
12/// This type has derive of [`clap::Parser`](https://docs.rs/clap/4.5.24/clap/trait.Parser.html), which allows to parse
13/// initial input on cli, which may be incomplete
14pub trait ToCli {
15    type CliVariant;
16}
17
18impl ToCli for String {
19    type CliVariant = String;
20}
21
22impl ToCli for u128 {
23    type CliVariant = u128;
24}
25
26impl ToCli for u64 {
27    type CliVariant = u64;
28}
29
30impl ToCli for bool {
31    type CliVariant = bool;
32}
33
34// TODO: the trait can clearly be shortened/renamed to `ContextScope`
35pub trait ToInteractiveClapContextScope {
36    type InteractiveClapContextScope;
37}
38
39pub trait ToCliArgs {
40    fn to_cli_args(&self) -> std::collections::VecDeque<String>;
41}
42
43pub enum ResultFromCli<T, E> {
44    Ok(T),
45    Cancel(Option<T>),
46    Back,
47    Err(Option<T>, E),
48}
49
50/// This trait drives the state machine of `interactive_clap`
51///
52/// It selects next command variants with [inquire::Select](https://docs.rs/inquire/0.6.2/inquire/struct.Select.html)
53/// and prompts for non-optional arguments with [inquire::CustomType](https://docs.rs/inquire/0.6.2/inquire/struct.CustomType.html)  
54pub trait FromCli {
55    type FromCliContext;
56    type FromCliError;
57    fn from_cli(
58        optional_clap_variant: Option<<Self as ToCli>::CliVariant>,
59        context: Self::FromCliContext,
60    ) -> ResultFromCli<<Self as ToCli>::CliVariant, Self::FromCliError>
61    where
62        Self: Sized + ToCli;
63}
64
65pub enum SelectVariantOrBack<T: strum::EnumMessage> {
66    Variant(T),
67    Back,
68}
69impl<T: strum::EnumMessage> std::fmt::Display for SelectVariantOrBack<T> {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        if let Self::Variant(variant) = self {
72            f.write_str(variant.get_message().unwrap())
73        } else {
74            f.write_str("back")
75        }
76    }
77}