Skip to main content

memo_cli/
app.rs

1use std::ffi::OsString;
2
3use clap::{Parser, error::ErrorKind};
4
5use crate::cli::{Cli, OutputMode};
6use crate::errors::AppError;
7
8pub fn run() -> i32 {
9    run_with_args(std::env::args_os())
10}
11
12pub fn run_with_args<I, T>(args: I) -> i32
13where
14    I: IntoIterator<Item = T>,
15    T: Into<OsString> + Clone,
16{
17    let cli = match Cli::try_parse_from(args) {
18        Ok(cli) => cli,
19        Err(err) => {
20            let kind = err.kind();
21            match kind {
22                ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => {
23                    print!("{err}");
24                    return 0;
25                }
26                _ => {
27                    eprint!("{err}");
28                    return 64;
29                }
30            }
31        }
32    };
33
34    let output_mode = match cli.resolve_output_mode() {
35        Ok(mode) => mode,
36        Err(err) => {
37            eprintln!("{}", err.message());
38            return err.exit_code();
39        }
40    };
41
42    match crate::commands::run(&cli, output_mode) {
43        Ok(()) => 0,
44        Err(err) => report_error(&cli, output_mode, &err),
45    }
46}
47
48fn report_error(cli: &Cli, output_mode: OutputMode, err: &AppError) -> i32 {
49    if output_mode.is_json()
50        && let Err(output_err) =
51            crate::output::emit_json_error(cli.schema_version(), cli.command_id(), err)
52    {
53        eprintln!("{}", output_err.message());
54    }
55
56    if !output_mode.is_json() {
57        eprintln!("{}", err.message());
58    }
59
60    err.exit_code()
61}