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
pub mod args;
pub mod bootstrap;
pub mod error;
pub mod explorer;
pub mod fragment;
pub mod generators;
pub mod rest;

use clap::Parser;
pub use error::MjolnirError;
use jortestkit::{load::Monitor, prelude::ProgressBarMode};
use std::error::Error;

#[derive(Parser)]
#[clap(rename_all = "kebab-case")]
pub struct Mjolnir {
    /// display full version details (software version, source version, targets and compiler used)
    #[clap(long = "full-version")]
    full_version: bool,

    /// display the sources version, allowing to check the source's hash used to compile this executable.
    /// this option is useful for scripting retrieving the logs of the version of this application.
    #[clap(long = "source-version")]
    source_version: bool,

    #[clap(subcommand)]
    command: Option<MjolnirCommand>,
}

#[allow(clippy::large_enum_variant)]
/// Jormungandr Load CLI toolkit
#[derive(Parser)]
#[clap(rename_all = "kebab-case")]
pub enum MjolnirCommand {
    /// Passive Nodes bootstrap
    Passive(bootstrap::ClientLoadCommand),
    /// Explorer load
    Explorer(explorer::ExplorerLoadCommand),
    /// Fragment load
    #[clap(subcommand)]
    Fragment(fragment::FragmentLoadCommand),
    /// Rest load
    Rest(rest::RestLoadCommand),
}

impl Mjolnir {
    pub fn exec(self) -> Result<(), Box<dyn Error>> {
        use std::io::Write as _;
        if self.full_version {
            Ok(writeln!(std::io::stdout(), "{}", env!("FULL_VERSION"))?)
        } else if self.source_version {
            Ok(writeln!(std::io::stdout(), "{}", env!("SOURCE_VERSION"))?)
        } else if let Some(cmd) = self.command {
            cmd.exec()
        } else {
            writeln!(std::io::stderr(), "No command, try `--help'")?;
            std::process::exit(1);
        }
    }
}

impl MjolnirCommand {
    pub fn exec(self) -> Result<(), Box<dyn Error>> {
        use self::MjolnirCommand::*;
        match self {
            Passive(bootstrap) => bootstrap.exec()?,
            Explorer(explorer) => explorer.exec()?,
            Fragment(fragment) => fragment.exec()?,
            Rest(rest) => rest.exec()?,
        };
        Ok(())
    }
}

pub fn build_monitor(progress_bar_mode: &ProgressBarMode) -> Monitor {
    match progress_bar_mode {
        ProgressBarMode::Monitor => Monitor::Progress(100),
        ProgressBarMode::Standard => Monitor::Standard(100),
        ProgressBarMode::None => Monitor::Disabled(10),
    }
}