version_manager/cli/
command.rs

1use super::VersionCommand;
2use crate::{version::VersionFile, CommandRun, VersionError, VersionResult};
3use clap::{
4    builder::{styling::AnsiColor, Styles},
5    value_parser, Command, CommandFactory, Parser,
6};
7use clap_complete::{generate, Generator, Shell};
8use std::io;
9
10const STYLE: Styles = Styles::styled()
11    .header(AnsiColor::Yellow.on_default())
12    .error(AnsiColor::Red.on_default())
13    .usage(AnsiColor::Green.on_default())
14    .literal(AnsiColor::BrightBlue.on_default())
15    .placeholder(AnsiColor::Blue.on_default())
16    .valid(AnsiColor::Cyan.on_default())
17    .invalid(AnsiColor::Magenta.on_default());
18
19#[derive(Parser, Debug, Clone)]
20#[command(arg_required_else_help(true), styles = STYLE, name = "version")]
21/// A tool for managing the version of a project
22pub struct Cli {
23    #[command(subcommand)]
24    pub command: Option<VersionCommand>,
25    #[arg(long, value_parser = value_parser!(Shell), exclusive = true)]
26    /// Generate shell completions
27    pub generator: Option<Shell>,
28}
29
30impl Cli {
31    fn print_completions<G: Generator>(gen: G, cmd: &mut Command) -> VersionResult<()> {
32        generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
33        Ok(())
34    }
35}
36
37impl CommandRun for Cli {
38    fn run(&self, version: &mut VersionFile) -> VersionResult<()> {
39        if let Some(generator) = self.generator {
40            let mut cmd = Cli::command();
41            Self::print_completions(generator, &mut cmd)
42        } else if let Some(command) = &self.command {
43            command.run(version)
44        } else {
45            Err(VersionError::NoCommand)
46        }
47    }
48}