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

Code before:
                .fold(HashSet::new(), |mut acc, components| {
                    acc.extend(components.iter().cloned());
                    acc
                })
        }))
    }
}

#[derive(Debug, Clone, Copy)]
pub enum PagingMode {
    Always,
    QuitIfOneScreen,
    Never,
}

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<(usize, usize)>,
}

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

fn get_ranges(value: Option<&str>) -> Option<(usize, usize)> {
    match value {
        None => None,
        Some(str_range) => {
            let mut new_range = (usize::min_value(), usize::max_value());
            if str_range.bytes().nth(0).expect("Something should be here!") == b':' {
                new_range.1 = str_range[1..].parse().expect("This should be a number!");
                return Some(new_range);
            } else if str_range.bytes().last().expect("There should be a last!") == b':' {
                new_range.0 = str_range[..str_range.len() - 1]
                    .parse()
                    .expect("This should be a number!");
                return Some(new_range);
            }

            let line_numbers: Vec<&str> = str_range.split(':').collect();
            if line_numbers.len() == 2 {

Review comment (suggestion):
I think it would be worth to write a small `struct LineRange` that instead of `(usize, usize)`. The `get_ranges`/`parse_ranges` function could then be a static `LineRange::new` or `LineRange::from` function.

I think it would also be cleaner to represent the open bounds as `None` instead of `min_value`/`max_value`:
```rust
struct LineRange {
    lower: Option<usize>,
    upper: Option<usize>,
}

impl LineRange {
    pub fn new(value: &str) -> Self {
        // ...
    }
}
```
This might also complicate some things, so I'm not quite sure.

Code after:
            values_t!(matches.values_of("style"), OutputComponent)?
                .into_iter()
                .map(|style| style.components(self.interactive_output))
                .fold(HashSet::new(), |mut acc, components| {
                    acc.extend(components.iter().cloned());
                    acc
                })
        }))
    }
}

#[derive(Debug, Clone, Copy)]
pub enum PagingMode {
    Always,
    QuitIfOneScreen,
    Never,
}

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(),