leetcode_cli/cmds/
completions.rs

1//! Completions command
2
3use super::Command;
4use crate::err::Error;
5use async_trait::async_trait;
6use clap::{Arg, ArgAction, ArgMatches, Command as ClapCommand};
7use clap_complete::{generate, Generator, Shell};
8
9/// Abstract shell completions command
10///
11/// ```sh
12/// Generate shell Completions
13
14/// USAGE:
15///     leetcode completions <shell>
16
17/// ARGUMENTS:
18///     <shell>  [possible values: bash, elvish, fish, powershell, zsh]
19/// ```
20pub struct CompletionCommand;
21
22#[async_trait]
23impl Command for CompletionCommand {
24    /// `pick` usage
25    fn usage() -> ClapCommand {
26        ClapCommand::new("completions")
27            .about("Generate shell Completions")
28            .visible_alias("c")
29            .arg(
30                Arg::new("shell")
31                    .action(ArgAction::Set)
32                    .value_parser(clap::value_parser!(Shell)),
33            )
34    }
35
36    async fn handler(_m: &ArgMatches) -> Result<(), Error> {
37        // defining custom handler to print the completions. Handler method signature limits taking
38        // other params. We need &ArgMatches and &mut ClapCommand to generate completions.
39        println!("Don't use this handler. Does not implement the functionality to print completions. Use completions_handler() below.");
40        Ok(())
41    }
42}
43
44fn get_completions_string<G: Generator>(gen: G, cmd: &mut ClapCommand) -> Result<String, Error> {
45    let mut v: Vec<u8> = Vec::new();
46    let name = cmd.get_name().to_string();
47    generate(gen, cmd, name, &mut v);
48    Ok(String::from_utf8(v)?)
49}
50
51pub fn completion_handler(m: &ArgMatches, cmd: &mut ClapCommand) -> Result<(), Error> {
52    let shell = *m.get_one::<Shell>("shell").unwrap_or(
53        // if shell value is not provided try to get from the environment
54        &Shell::from_env().ok_or(Error::MatchError)?,
55    );
56    let completions = get_completions_string(shell, cmd)?;
57    println!("{}", completions);
58    Ok(())
59}