Skip to main content

agent_first_mail/cli/
parse.rs

1use super::{Cli, Command};
2use agent_first_data::{cli_parse_log_filters, cli_parse_output, OutputFormat};
3use clap::{CommandFactory, Parser};
4
5pub struct ParsedArgs {
6    pub command: Command,
7    pub output: OutputFormat,
8    pub log: Vec<String>,
9}
10
11pub fn parse_args() -> Result<ParsedArgs, String> {
12    let cli = Cli::try_parse().map_err(|e| e.to_string())?;
13    let output = cli_parse_output(&cli.output)?;
14    let log = normalize_log_filters(&cli.log, cli.verbose)?;
15    match cli.command {
16        Some(command) => Ok(ParsedArgs {
17            command,
18            output,
19            log,
20        }),
21        None => Err("no command provided; try: afmail --help".to_string()),
22    }
23}
24
25fn normalize_log_filters(entries: &[String], verbose: bool) -> Result<Vec<String>, String> {
26    let mut filters = if verbose {
27        vec![
28            "startup".to_string(),
29            "request".to_string(),
30            "progress".to_string(),
31            "retry".to_string(),
32        ]
33    } else {
34        Vec::new()
35    };
36    for entry in cli_parse_log_filters(entries) {
37        if !is_supported_log_filter(&entry) {
38            return Err(format!(
39                "--log unsupported category '{entry}'; expected one of: startup, request, progress, retry"
40            ));
41        }
42        if !filters.contains(&entry) {
43            filters.push(entry);
44        }
45    }
46    Ok(filters)
47}
48
49fn is_supported_log_filter(value: &str) -> bool {
50    matches!(value, "startup" | "request" | "progress" | "retry")
51}
52
53pub fn command() -> clap::Command {
54    Cli::command()
55}