pass_tool/
cli.rs

1use clap::{Parser, Subcommand};
2
3use crate::{interfaces::ActionResult, Playbook};
4
5#[derive(Parser)]
6struct Args {
7    #[command(subcommand)]
8    command: Option<Commands>,
9}
10
11#[derive(Subcommand)]
12enum Commands {
13    /// Show information about playbook
14    About,
15    /// Show source code of playbook
16    Source,
17}
18
19#[derive(Parser)]
20struct ArgsWithInput {
21    #[command(subcommand)]
22    command: CommandsWithInput,
23}
24
25#[derive(Subcommand)]
26enum CommandsWithInput {
27    /// Show information about playbook
28    About {
29        /// Input data for playbook
30        input: Option<String>,
31    },
32    /// Show source code of playbook
33    Source,
34    /// Apply playbook
35    Apply {
36        /// Input data for playbook
37        input: String,
38    },
39}
40
41fn print_about(playbook: &Playbook) {
42    println!("# Playbook: {}", playbook.name);
43    println!();
44    println!("{}", playbook.description);
45}
46
47pub fn run_cli(playbook: Playbook, source: &'static str) {
48    let args = Args::parse();
49    if let Some(cmd) = args.command {
50        match cmd {
51            Commands::About => print_about(&playbook),
52            Commands::Source => println!("{source}"),
53        }
54    } else if playbook.apply() == ActionResult::Fail {
55        std::process::exit(1);
56    }
57}
58
59impl From<Playbook> for Result<Playbook, String> {
60    fn from(value: Playbook) -> Self {
61        Ok(value)
62    }
63}
64
65pub fn run_cli_with_input<GetPlaybook>(
66    get_playbook: GetPlaybook,
67    input_help: &'static str,
68    source: &'static str,
69) where
70    GetPlaybook: FnOnce(&[u8]) -> Result<Playbook, String>,
71{
72    let args = ArgsWithInput::parse();
73    match args.command {
74        CommandsWithInput::About { input: Some(input) } => match get_playbook(input.as_bytes()) {
75            Ok(pb) => {
76                print_about(&pb);
77                println!();
78                println!("{input_help}");
79            }
80            Err(e) => {
81                println!("{e}");
82                std::process::exit(1);
83            }
84        },
85        CommandsWithInput::About { input: None } => {
86            println!("{input_help}");
87        }
88        CommandsWithInput::Source => println!("{source}"),
89        CommandsWithInput::Apply { input } => match get_playbook(input.as_bytes()) {
90            Ok(pb) => {
91                if pb.apply() == ActionResult::Fail {
92                    std::process::exit(1);
93                }
94            }
95            Err(e) => {
96                println!("{e}");
97                std::process::exit(1);
98            }
99        },
100    };
101}