Repository: sharkdp/bat
File: src/less.rs (Rust)

Code before:
    BusyBox,
}

pub fn retrieve_less_version(less_path: &dyn AsRef<OsStr>) -> Option<LessVersion> {
    let resolved_path = grep_cli::resolve_binary(less_path.as_ref()).ok()?;

    let cmd = Command::new(resolved_path).arg("--version").output().ok()?;
    if cmd.status.success() {
        parse_less_version(&cmd.stdout)
    } else {
        parse_less_version(&cmd.stderr)
    }
}

fn parse_less_version(output: &[u8]) -> Option<LessVersion> {
    match std::str::from_utf8(output) {
        Ok(version) if version.starts_with("less ") => {
            let end = (&version[5..]).find(|c: char| !c.is_ascii_digit())? + 5;
            Some(LessVersion::Less(version[5..end].parse::<usize>().ok()?))
        }
        Ok(version) if version.contains("BusyBox ") => Some(LessVersion::BusyBox),
        _ => None,
    }
}

#[test]
fn test_parse_less_version_487() {
    let output = b"less 487 (GNU regular expressions)
Copyright (C) 1984-2016  Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less";

    assert_eq!(Some(LessVersion::Less(487)), parse_less_version(output));
}

#[test]
fn test_parse_less_version_529() {
    let output = b"less 529 (Spencer V8 regular expressions)
Copyright (C) 1984-2017  Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less";

    assert_eq!(Some(LessVersion::Less(529)), parse_less_version(output));
}


Review comment (bug):
It would be good if we could continue being cautious about encoding, and check if this is less or BusyBox before assuming the output is UTF-8. Otherwise we are more or less certain to crash in scenarios where people use odd pagers (for whatever reason) that does not output UTF-8.

Code after:
    BusyBox,
}

pub fn retrieve_less_version(less_path: &dyn AsRef<OsStr>) -> Option<LessVersion> {
    let resolved_path = grep_cli::resolve_binary(less_path.as_ref()).ok()?;

    let cmd = Command::new(resolved_path).arg("--version").output().ok()?;
    if cmd.status.success() {
        parse_less_version(&cmd.stdout)
    } else {
        parse_less_version_busybox(&cmd.stderr)
    }
}

fn parse_less_version(output: &[u8]) -> Option<LessVersion> {
    if !output.starts_with(b"less ") {
        return None;
    }

    let version = std::str::from_utf8(&output[5..]).ok()?;
    let end = version.find(|c: char| !c.is_ascii_digit())?;
    Some(LessVersion::Less(version[..end].parse::<usize>().ok()?))
}

fn parse_less_version_busybox(output: &[u8]) -> Option<LessVersion> {
    match std::str::from_utf8(output) {
        Ok(version) if version.contains("BusyBox ") => Some(LessVersion::BusyBox),
        _ => None,
    }
}

#[test]
fn test_parse_less_version_487() {
    let output = b"less 487 (GNU regular expressions)
Copyright (C) 1984-2016  Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less";

    assert_eq!(Some(LessVersion::Less(487)), parse_less_version(output));
}

#[test]
fn test_parse_less_version_529() {
    let output = b"less 529 (Spencer V8 regular expressions)
Copyright (C) 1984-2017  Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,