pub fn parse_args() -> Mode {
    let matches = app().get_matches();

    if let Some(path) = matches.value_of("dump-syntax") {
        return Mode::DumpSyntax {
            path: path.to_string(),
        };
    }

    if let Some(path) = matches.value_of("dump-ts") {
        return Mode::DumpTreeSitter {
            path: path.to_string(),
        };
    }

    // TODO: Use OsString rather than forcing paths to be valid UTF-8.
    let args: Vec<_> = matches.values_of_lossy("paths").unwrap_or_default();
    info!("CLI arguments: {:?}", args);

    // TODO: document these different ways of calling difftastic.
    let (display_path, lhs_path, rhs_path) = match &args[..] {
        [lhs_path, rhs_path] => (
            rhs_path.to_string(),
            lhs_path.to_string(),
            rhs_path.to_string(),
        ),
        [display_path, lhs_tmp_file, _lhs_hash, _lhs_mode, rhs_tmp_file, _rhs_hash, _rhs_mode] => {
            // https://git-scm.com/docs/git#Documentation/git.txt-codeGITEXTERNALDIFFcode
            (
                display_path.to_string(),
                lhs_tmp_file.to_string(),
                rhs_tmp_file.to_string(),
            )
        }
        [_old_name, lhs_tmp_file, _lhs_hash, _lhs_mode, rhs_tmp_file, _rhs_hash, _rhs_mode, new_name, _similarity] =>
        {
            // Rename file.
            // TODO: mention old name as well as diffing.
            // TODO: where does git document these 9 arguments?
            (
                new_name.to_string(),
                lhs_tmp_file.to_string(),
                rhs_tmp_file.to_string(),
            )
        }
        _ => {
            if !args.is_empty() {
                eprintln!(
                    "error: Difftastic does not support being called with {} argument{}.\n",
                    args.len(),
                    if args.len() == 1 { "" } else { "s" }
                );
            }
            eprintln!("USAGE:\n\n    {}\n", USAGE);
            eprintln!("For more information try --help");
            std::process::exit(1);
        }
    };

    let display_width = if let Some(arg_width) = matches.value_of("width") {
        arg_width
            .parse::<usize>()
            .expect("Already validated by clap")
    } else {
        let env_width = if let Ok(env_width) = env::var("DFT_WIDTH") {
            env_width.parse::<usize>().ok()
        } else {
            None
        };
        env_width.unwrap_or_else(detect_display_width)
    };

    let color_output = if let Some(color_when) = matches.value_of("color") {
        if color_when == "always" {
            ColorOutput::Always
        } else if color_when == "never" {
            ColorOutput::Never
        } else {
            ColorOutput::Auto
        }
    } else {
        ColorOutput::Auto
    };

    let background_color = if let Some(background) = matches.value_of("background") {
        if background == "light" {
            BackgroundColor::Light
        } else {
            BackgroundColor::Dark
        }
    } else {
        if let Ok(background) = env::var("DFT_BACKGROUND") {
            if background == "light" {
                BackgroundColor::Light
            } else {
                BackgroundColor::Dark
            }
        } else {
            BackgroundColor::Dark
        }
    };

    let node_limit: u32 = if matches.occurrences_of("node-limit") == 0 {
        if let Ok(env_width) = env::var("DFT_NODE_LIMIT") {
            env_width.parse::<u32>().ok().unwrap_or(DEFAULT_NODE_LIMIT)
        } else {
            DEFAULT_NODE_LIMIT
        }
    } else {
        matches
            .value_of("node-limit")
            .expect("Always present as we've given clap a default")
            .parse::<u32>()
            .expect("Value already validated by clap")
    };

    let byte_limit: usize = if matches.occurrences_of("byte-limit") == 0 {
        if let Ok(env_width) = env::var("DFT_BYTE_LIMIT") {
            env_width
                .parse::<usize>()
                .ok()
                .unwrap_or(DEFAULT_BYTE_LIMIT)
        } else {
            DEFAULT_BYTE_LIMIT
        }
    } else {
        matches
            .value_of("byte-limit")
            .expect("Always present as we've given clap a default")
            .parse::<usize>()
            .expect("Value already validated by clap")
    };

    let print_unchanged = !matches.is_present("skip-unchanged");
    let missing_as_empty = matches.is_present("missing-as-empty");

    Mode::Diff {
        node_limit,
        byte_limit,
        print_unchanged,
        missing_as_empty,
        background_color,
        color_output,
        display_width,
        display_path,
        lhs_path,
        rhs_path,
    }
}
/// Parse CLI arguments passed to the binary.
Parse CLI arguments passed to the binary.
Parse CLI arguments passed to the binary .
pub fn parse_args() -> Mode {
    let matches = app().get_matches();
    if let Some(path) = matches.value_of("dump-syntax") {
        return Mode::DumpSyntax {
            path: path.to_string(),
        };
    }
    if let Some(path) = matches.value_of("dump-ts") {
        return Mode::DumpTreeSitter {
            path: path.to_string(),
        };
    }
    // TODO: Use OsString rather than forcing paths to be valid UTF-8.
    let args: Vec<_> = matches.values_of_lossy("paths").unwrap_or_default();
    info!("CLI arguments: {:?}", args);
    // TODO: document these different ways of calling difftastic.
    let (display_path, lhs_path, rhs_path) = match &args[..] {
        [lhs_path, rhs_path] => (
            rhs_path.to_string(),
            lhs_path.to_string(),
            rhs_path.to_string(),
        ),
        [display_path, lhs_tmp_file, _lhs_hash, _lhs_mode, rhs_tmp_file, _rhs_hash, _rhs_mode] => {
            // https://git-scm.com/docs/git#Documentation/git.txt-codeGITEXTERNALDIFFcode
            (
                display_path.to_string(),
                lhs_tmp_file.to_string(),
                rhs_tmp_file.to_string(),
            )
        }
        [_old_name, lhs_tmp_file, _lhs_hash, _lhs_mode, rhs_tmp_file, _rhs_hash, _rhs_mode, new_name, _similarity] =>
        {
            // Rename file.
            // TODO: mention old name as well as diffing.
            // TODO: where does git document these 9 arguments?
            (
                new_name.to_string(),
                lhs_tmp_file.to_string(),
                rhs_tmp_file.to_string(),
            )
        }
        _ => {
            if !args.is_empty() {
                eprintln!(
                    "error: Difftastic does not support being called with {} argument{}.\n",
                    args.len(),
                    if args.len() == 1 { "" } else { "s" }
                );
            }
            eprintln!("USAGE:\n\n    {}\n", USAGE);
            eprintln!("For more information try --help");
            std::process::exit(1);
        }
    };
    let display_width = if let Some(arg_width) = matches.value_of("width") {
        arg_width
            .parse::<usize>()
            .expect("Already validated by clap")
    } else {
        let env_width = if let Ok(env_width) = env::var("DFT_WIDTH") {
            env_width.parse::<usize>().ok()
        } else {
            None
        };
        env_width.unwrap_or_else(detect_display_width)
    };
    let color_output = if let Some(color_when) = matches.value_of("color") {
        if color_when == "always" {
            ColorOutput::Always
        } else if color_when == "never" {
            ColorOutput::Never
        } else {
            ColorOutput::Auto
        }
    } else {
        ColorOutput::Auto
    };
    let background_color = if let Some(background) = matches.value_of("background") {
        if background == "light" {
            BackgroundColor::Light
        } else {
            BackgroundColor::Dark
        }
    } else {
        if let Ok(background) = env::var("DFT_BACKGROUND") {
            if background == "light" {
                BackgroundColor::Light
            } else {
                BackgroundColor::Dark
            }
        } else {
            BackgroundColor::Dark
        }
    };
    let node_limit: u32 = if matches.occurrences_of("node-limit") == 0 {
        if let Ok(env_width) = env::var("DFT_NODE_LIMIT") {
            env_width.parse::<u32>().ok().unwrap_or(DEFAULT_NODE_LIMIT)
        } else {
            DEFAULT_NODE_LIMIT
        }
    } else {
        matches
            .value_of("node-limit")
            .expect("Always present as we've given clap a default")
            .parse::<u32>()
            .expect("Value already validated by clap")
    };
    let byte_limit: usize = if matches.occurrences_of("byte-limit") == 0 {
        if let Ok(env_width) = env::var("DFT_BYTE_LIMIT") {
            env_width
                .parse::<usize>()
                .ok()
                .unwrap_or(DEFAULT_BYTE_LIMIT)
        } else {
            DEFAULT_BYTE_LIMIT
        }
    } else {
        matches
            .value_of("byte-limit")
            .expect("Always present as we've given clap a default")
            .parse::<usize>()
            .expect("Value already validated by clap")
    };
    let print_unchanged = !matches.is_present("skip-unchanged");
    let missing_as_empty = matches.is_present("missing-as-empty");
    Mode::Diff {
        node_limit,
        byte_limit,
        print_unchanged,
        missing_as_empty,
        background_color,
        color_output,
        display_width,
        display_path,
        lhs_path,
        rhs_path,
    }
}
pub fn parse_args ( ) -> Mode { let matches = app ( ) . get_matches ( ) ; if let Some ( path ) = matches . value_of ( " " ) { return Mode :: DumpSyntax { path : path . to_string ( ) , } ; } if let Some ( path ) = matches . value_of ( " " ) { return Mode :: DumpTreeSitter { path : path . to_string ( ) , } ; } // TODO: Use OsString rather than forcing paths to be valid UTF-8. let args : Vec < _ > = matches . values_of_lossy ( " " ) . unwrap_or_default ( ) ; info ! ( " " args ) ; // TODO: document these different ways of calling difftastic. let ( display_path , lhs_path , rhs_path ) = match & args [ .. ] { [ lhs_path , rhs_path ] => ( rhs_path . to_string ( ) , lhs_path . to_string ( ) , rhs_path . to_string ( ) , ) , [ display_path , lhs_tmp_file , _lhs_hash , _lhs_mode , rhs_tmp_file , _rhs_hash , _rhs_mode ] => { // https://git-scm.com/docs/git#Documentation/git.txt-codeGITEXTERNALDIFFcode ( display_path . to_string ( ) , lhs_tmp_file . to_string ( ) , rhs_tmp_file . to_string ( ) , ) } [ _old_name , lhs_tmp_file , _lhs_hash , _lhs_mode , rhs_tmp_file , _rhs_hash , _rhs_mode , new_name , _similarity ] => { // Rename file. // TODO: mention old name as well as diffing. // TODO: where does git document these 9 arguments? ( new_name . to_string ( ) , lhs_tmp_file . to_string ( ) , rhs_tmp_file . to_string ( ) , ) } _ => { if ! args . is_empty ( ) { eprintln ! ( " \n " args len ( ) if args len ( ) 1 { " " } else { " " } ) ; } eprintln ! ( " \n \n \n " USAGE ) ; eprintln ! ( " " ) ; std :: process :: exit ( 1 ) ; } } ; let display_width = if let Some ( arg_width ) = matches . value_of ( " " ) { arg_width . parse :: < usize > ( ) . expect ( " " ) } else { let env_width = if let Ok ( env_width ) = env :: var ( " " ) { env_width . parse :: < usize > ( ) . ok ( ) } else { None } ; env_width . unwrap_or_else ( detect_display_width ) } ; let color_output = if let Some ( color_when ) = matches . value_of ( " " ) { if color_when == " " { ColorOutput :: Always } else if color_when == " " { ColorOutput :: Never } else { ColorOutput :: Auto } } else { ColorOutput :: Auto } ; let background_color = if let Some ( background ) = matches . value_of ( " " ) { if background == " " { BackgroundColor :: Light } else { BackgroundColor :: Dark } } else { if let Ok ( background ) = env :: var ( " " ) { if background == " " { BackgroundColor :: Light } else { BackgroundColor :: Dark } } else { BackgroundColor :: Dark } } ; let node_limit : u32 = if matches . occurrences_of ( " " ) == 0 { if let Ok ( env_width ) = env :: var ( " " ) { env_width . parse :: < u32 > ( ) . ok ( ) . unwrap_or ( DEFAULT_NODE_LIMIT ) } else { DEFAULT_NODE_LIMIT } } else { matches . value_of ( " " ) . expect ( " " ) . parse :: < u32 > ( ) . expect ( " " ) } ; let byte_limit : usize = if matches . occurrences_of ( " " ) == 0 { if let Ok ( env_width ) = env :: var ( " " ) { env_width . parse :: < usize > ( ) . ok ( ) . unwrap_or ( DEFAULT_BYTE_LIMIT ) } else { DEFAULT_BYTE_LIMIT } } else { matches . value_of ( " " ) . expect ( " " ) . parse :: < usize > ( ) . expect ( " " ) } ; let print_unchanged = ! matches . is_present ( " " ) ; let missing_as_empty = matches . is_present ( " " ) ; Mode :: Diff { node_limit , byte_limit , print_unchanged , missing_as_empty , background_color , color_output , display_width , display_path , lhs_path , rhs_path , } }
Parse CLI arguments passed to the binary.
Parse CLI arguments passed to the binary .