tovuk 0.1.114

Use Tovuk scraper APIs from a native CLI.
use super::{
    model::CliOptions,
    values::{set_boolean_flag, set_string_flag},
};
use crate::cli::errors::{Result, agent_error};

const LONG_FLAG_PREFIX: &str = "\x2d\x2d";

pub(super) fn parse_flag(arg: &str) -> Option<(&str, Option<String>)> {
    if !arg.starts_with('-') {
        return None;
    }
    if arg.starts_with(LONG_FLAG_PREFIX)
        && let Some(index) = arg.find('=')
        && index > 2
    {
        return Some((&arg[..index], Some(arg[index + 1..].to_owned())));
    }
    Some((arg, None))
}

pub(super) fn apply_flag(
    cli: &mut CliOptions,
    name: &str,
    inline: Option<String>,
    argv: &[String],
    index: usize,
) -> Result<usize> {
    let json_output = cli.output.json;
    if let Some(consumed) = apply_boolean_flag(cli, name, inline.as_ref(), json_output)? {
        return Ok(consumed);
    }
    apply_value_flag(cli, name, inline, argv, index)
}

fn apply_boolean_flag(
    cli: &mut CliOptions,
    name: &str,
    inline: Option<&String>,
    json_output: bool,
) -> Result<Option<usize>> {
    match name {
        "--help" | "-h" => set_boolean_flag(inline, || cli.output.help = true, name, json_output),
        "--version" | "-v" | "-V" => {
            set_boolean_flag(inline, || cli.output.version = true, name, json_output)
        }
        "--json" => set_boolean_flag(inline, || cli.output.json = true, name, json_output),
        _ => return Ok(None),
    }
    .map(Some)
}

fn apply_value_flag(
    cli: &mut CliOptions,
    name: &str,
    inline: Option<String>,
    argv: &[String],
    index: usize,
) -> Result<usize> {
    if name == "--output" {
        return apply_output_value_flag(cli, name, inline, argv, index);
    }
    let json_output = cli.output.json;
    let Some(target) = string_flag_target(cli, name) else {
        return invalid_value_flag_dispatch(cli, name);
    };
    set_string_flag(target, name, inline, argv, index, json_output)
}

fn apply_output_value_flag(
    cli: &mut CliOptions,
    name: &str,
    inline: Option<String>,
    argv: &[String],
    index: usize,
) -> Result<usize> {
    let json_output = cli.output.json;
    let value = super::values::flag_value(name, inline, argv, index, json_output)?;
    set_output_format(cli, value.as_str(), name, json_output)?;
    Ok(super::values::flag_consumed(argv, index))
}

pub(super) fn set_output_format(
    cli: &mut CliOptions,
    value: &str,
    source: &str,
    json_output: bool,
) -> Result<()> {
    if value.eq_ignore_ascii_case("json") {
        cli.output.json = true;
        return Ok(());
    }
    Err(agent_error(
        "invalid_argument",
        format!("{source} must be `json`."),
        format!("Set {source} to `json`, or omit it for default command output."),
        json_output,
    ))
}

fn invalid_value_flag_dispatch(cli: &CliOptions, name: &str) -> Result<usize> {
    Err(agent_error(
        "unknown_argument",
        format!("Unknown Tovuk option: {name}."),
        "Run `tovuk --help`, remove or correct the unsupported option, then retry.",
        cli.output.json,
    ))
}

fn string_flag_target<'a>(cli: &'a mut CliOptions, name: &str) -> Option<&'a mut String> {
    match name {
        "--limit" => Some(&mut cli.limit),
        "--cursor" => Some(&mut cli.cursor),
        "--top-up-usd-cents" => Some(&mut cli.top_up_usd_cents),
        "--token" => Some(&mut cli.token),
        "--failing-command" => Some(&mut cli.failing_command),
        "--first-log-line" => Some(&mut cli.first_log_line),
        "--request-id" => Some(&mut cli.request_id),
        "--scraper-id" => Some(&mut cli.scraper_id),
        "--severity" => Some(&mut cli.severity),
        _ => None,
    }
}