1
use clap::{
2
  Args,
3
  Subcommand,
4
};
5

            
6
use super::context::Context;
7

            
8
pub use export_key::ExportKey;
9
pub use generate_key::GenerateKey;
10
pub use list_keys::ListKeys;
11
pub use purge_key::PurgeKey;
12

            
13
mod export_key;
14
mod generate_key;
15
mod list_keys;
16
mod purge_key;
17

            
18
/// The help message for the key location
19
pub const KEY_LOCATION_HELP: &str = "The path to where the private keys are stored";
20

            
21
/// The struct that represents the key command
22
#[derive(Debug, Args)]
23
pub struct Key {
24
  /// The subcommand to run
25
  #[command(subcommand)]
26
  command: Option<KeyCommand>,
27

            
28
  /// The location to store the private key
29
  /// This is a global option that can be used with any subcommand
30
  /// If not provided, the default location will be used
31
  /// If the default location does not exist, it will be created
32
  /// If the default location is not provided, the key will not be created
33
  /// If the key already exists, it will not be created
34
  #[arg(short, long, help = KEY_LOCATION_HELP)]
35
  location: Option<String>,
36
}
37

            
38
/// The available subcommands for the key command
39
#[derive(Debug, Subcommand)]
40
enum KeyCommand {
41
  /// Generate a new private key
42
  #[command(visible_aliases = ["gen"], about = "Generate a new private key")]
43
  GenerateKey(GenerateKey),
44

            
45
  /// List all private keys
46
  #[command(visible_aliases = ["K", "ls"], about = "List all private keys")]
47
  ListKeys(ListKeys),
48

            
49
  /// Purge and remove a private key
50
  #[command(visible_aliases = ["rm"], about = "Purge and remove a private key")]
51
  PurgeKey(PurgeKey),
52

            
53
  /// Export a private key
54
  #[command(visible_aliases = ["export", "e"], about = "Export selected private key")]
55
  ExportKey(ExportKey),
56
}
57

            
58
impl Key {
59
  pub fn execute(&self, context: &mut Context) -> anyhow::Result<()> {
60
    if let Some(location) = &self.location {
61
      context.set_keys_location(location);
62
    }
63

            
64
    match &self.command {
65
      Some(command) => command.run(context),
66
      None => Err(anyhow::anyhow!("No subcommand provided")),
67
    }
68
  }
69
}
70

            
71
impl KeyCommand {
72
  pub fn run(&self, context: &Context) -> anyhow::Result<()> {
73
    match self {
74
      KeyCommand::GenerateKey(args) => args.execute(context),
75
      KeyCommand::ListKeys(args) => args.execute(context),
76
      KeyCommand::PurgeKey(args) => args.execute(context),
77
      KeyCommand::ExportKey(args) => args.execute(context),
78
    }
79
  }
80
}