1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use inquire::Select;
use strum::{EnumDiscriminants, EnumIter, EnumMessage, IntoEnumIterator};

mod add_key;
pub mod create_account;
mod delete_account;
mod delete_key;
mod export_account;
mod import_account;
mod list_keys;
pub mod storage_management;
mod view_account_summary;


pub const MIN_ALLOWED_TOP_LEVEL_ACCOUNT_LENGTH: usize = 2;

#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
#[interactive_clap(context = crate::GlobalContext)]
pub struct AccountCommands {
    #[interactive_clap(subcommand)]
    account_actions: AccountActions,
}

#[derive(Debug, EnumDiscriminants, Clone, interactive_clap::InteractiveClap)]
#[interactive_clap(context = crate::GlobalContext)]
#[strum_discriminants(derive(EnumMessage, EnumIter))]
#[non_exhaustive]
/// What do you want to do with an account?
pub enum AccountActions {
    #[strum_discriminants(strum(
        message = "view-account-summary    - View properties for an account"
    ))]
    /// View properties for an account
    ViewAccountSummary(self::view_account_summary::ViewAccountSummary),
    #[strum_discriminants(strum(
        message = "import-account          - Import existing account (a.k.a. \"sign in\")"
    ))]
    /// Import existing account (a.k.a. "sign in")
    ImportAccount(self::import_account::ImportAccountCommand),
    #[strum_discriminants(strum(message = "export-account          - Export existing account"))]
    /// Export existing account
    ExportAccount(self::export_account::ExportAccount),
    #[strum_discriminants(strum(message = "create-account          - Create a new account"))]
    /// Create a new account
    CreateAccount(self::create_account::CreateAccount),
    #[strum_discriminants(strum(message = "delete-account          - Delete an account"))]
    /// Delete an account
    DeleteAccount(self::delete_account::DeleteAccount),
    #[strum_discriminants(strum(
        message = "list-keys               - View a list of access keys of an account"
    ))]
    /// View a list of access keys of an account
    ListKeys(self::list_keys::ViewListKeys),
    #[strum_discriminants(strum(
        message = "add-key                 - Add an access key to an account"
    ))]
    /// Add an access key to an account
    AddKey(self::add_key::AddKeyCommand),
    #[strum_discriminants(strum(
        message = "delete-keys             - Delete access keys from an account"
    ))]
    /// Delete access keys from an account
    DeleteKeys(self::delete_key::DeleteKeysCommand),
    #[strum_discriminants(strum(
        message = "manage-storage-deposit  - Storage management: deposit, withdrawal, balance review"
    ))]
    /// Storage management for contract: deposit, withdrawal, balance review
    ManageStorageDeposit(self::storage_management::Contract),
}


#[derive(Debug, EnumDiscriminants, Clone, clap::ValueEnum)]
#[strum_discriminants(derive(EnumMessage, EnumIter))]
/// How do you want to pass the keys type?
pub enum KeysType {
    #[strum_discriminants(strum(
        message = "rsa2048 keypairs    - generate rsa2048 keytype"
    ))]
    Rsa2048,
    #[strum_discriminants(strum(message = "ed25519 keypairs    - generate ed25519 keytype"))]
    Ed25519,
}

impl interactive_clap::ToCli for KeysType {
    type CliVariant = KeysType;
}

impl std::str::FromStr for KeysType {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "rsa2048" => Ok(Self::Rsa2048),
            "ed25519" => Ok(Self::Ed25519),
            _ => Err("KeyType: incorrect value entered".to_string()),
        }
    }
}

impl std::fmt::Display for KeysType {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Self::Rsa2048 => write!(f, "rsa2048"),
            Self::Ed25519 => write!(f, "ed25519"),
        }
    }
}

impl std::fmt::Display for KeysTypeDiscriminants {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Self::Rsa2048 => write!(f, "rsa2048    - key type arguments"),
            Self::Ed25519 => write!(f, "ed25519    - key type arguments"),
        }
    }
}

pub fn input_keys_type() -> color_eyre::eyre::Result<Option<KeysType>> {
    let variants = KeysTypeDiscriminants::iter().collect::<Vec<_>>();
    let selected = Select::new(
        "How would you like to pass the key type?",
        variants,
    )
    .prompt()?;
    match selected {
        KeysTypeDiscriminants::Rsa2048 => Ok(Some(KeysType::Rsa2048)),
        KeysTypeDiscriminants::Ed25519 => Ok(Some(KeysType::Ed25519)),
    }
}