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

Code before:
pub struct Config<'a> {
    pub true_color: bool,
    pub output_wrap: OutputWrap,
    pub output_components: OutputComponents,
    pub language: Option<&'a str>,
    pub colored_output: bool,
    pub paging_mode: PagingMode,
    pub term_width: usize,
    pub files: Vec<Option<&'a str>>,
    pub theme: Option<&'a str>,
    pub line_range: Option<LineRange>,
}

fn is_truecolor_terminal() -> bool {
    env::var("COLORTERM")
        .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit")
        .unwrap_or(false)
}

pub struct LineRange {
    pub lower: usize,
    pub upper: usize,
}

impl LineRange {
    pub fn from(range_raw: &str) -> LineRange {
        LineRange::parse_range(range_raw).unwrap_or(LineRange::new())
    }

    pub fn new() -> LineRange {
        LineRange{
            lower: usize::min_value(),
            upper: usize::max_value(),
        }
    }

    pub fn parse_range(range_raw: &str) -> Result<LineRange> {
        let mut new_range = LineRange::new();

        if range_raw.bytes().nth(0).ok_or("No first byte")? == b':' {
            new_range.upper = range_raw[1..].parse()?;
            return Ok(new_range);
        } else if range_raw.bytes().last().ok_or("No last byte")? == b':' {
            new_range.lower = range_raw[..range_raw.len() - 1].parse()?;
            return Ok(new_range);
        }

        let line_numbers: Vec<&str> = range_raw.split(':').collect();
        if line_numbers.len() == 2 {
            new_range.lower = line_numbers[0].parse()?;
            new_range.upper = line_numbers[1].parse()?;

Review comment (suggestion):
I think this should also return a `Result<LineRange>` (by removing the `unwrap_or` call below). This way, we can pass the error messages through to the call-site.

Code after:

pub struct Config<'a> {
    pub true_color: bool,
    pub output_wrap: OutputWrap,
    pub output_components: OutputComponents,
    pub language: Option<&'a str>,
    pub colored_output: bool,
    pub paging_mode: PagingMode,
    pub term_width: usize,
    pub files: Vec<Option<&'a str>>,
    pub theme: Option<&'a str>,
    pub line_range: Option<LineRange>,
}

fn is_truecolor_terminal() -> bool {
    env::var("COLORTERM")
        .map(|colorterm| colorterm == "truecolor" || colorterm == "24bit")
        .unwrap_or(false)
}

pub struct LineRange {
    pub lower: usize,
    pub upper: usize,
}

impl LineRange {
    pub fn from(range_raw: &str) -> Result<LineRange> {
        LineRange::parse_range(range_raw)
    }

    pub fn new() -> LineRange {
        LineRange {
            lower: usize::min_value(),
            upper: usize::max_value(),
        }
    }

    pub fn parse_range(range_raw: &str) -> Result<LineRange> {
        let mut new_range = LineRange::new();

        if range_raw.bytes().nth(0).ok_or("Empty line range")? == b':' {
            new_range.upper = range_raw[1..].parse()?;
            return Ok(new_range);
        } else if range_raw.bytes().last().ok_or("Empty line range")? == b':' {
            new_range.lower = range_raw[..range_raw.len() - 1].parse()?;
            return Ok(new_range);
        }

        let line_numbers: Vec<&str> = range_raw.split(':').collect();
        if line_numbers.len() == 2 {
            new_range.lower = line_numbers[0].parse()?;