clap_utilities/
completion_generator.rs1use clap::{CommandFactory, Parser};
2use clap_complete::{generate, Shell};
3use std::{fs::File, io, path::PathBuf, process::ExitCode};
4use thiserror::Error;
5
6#[derive(Debug, Parser)]
8pub struct CompletionGenerator {
9 #[clap(long, short)]
11 name: String,
12 #[clap(long, short, value_enum)]
14 shell: Shell,
15 #[clap(long, short)]
17 output: PathBuf,
18}
19
20#[derive(Debug, Error)]
22pub enum Error {
23 #[error("{}: {error}", path.to_string_lossy())]
25 FileSystem {
26 path: PathBuf,
28 #[source]
30 error: io::Error,
31 },
32}
33
34impl CompletionGenerator {
35 pub fn run<App: CommandFactory>(self) -> Result<(), Error> {
37 let CompletionGenerator {
38 name,
39 shell,
40 output,
41 } = self;
42 let mut cmd = App::command();
43 let mut output_file = File::create(&output).map_err(|error| Error::FileSystem {
44 path: output.clone(),
45 error,
46 })?;
47 generate(shell, &mut cmd, name, &mut output_file);
48 Ok(())
49 }
50
51 pub fn main<App: CommandFactory>() -> ExitCode {
53 match CompletionGenerator::parse().run::<App>() {
54 Ok(()) => ExitCode::SUCCESS,
55 Err(error) => {
56 eprintln!("{error}");
57 ExitCode::FAILURE
58 }
59 }
60 }
61}