<commit_before>extern crate syntect;
use std::path::Path;
use syntect::parsing::SyntaxSet;
use syntect::highlighting::{Theme, ThemeSet, Style};
use syntect::util::as_24_bit_terminal_escaped;
use syntect::easy::HighlightFile;
use syntect::dumps::{from_dump_file, dump_to_file};

use std::io::BufRead;

fn load_theme(tm_file: &String) -> Theme {
    let tm_path = Path::new(tm_file);
    let tm_cache = tm_path.with_extension("tmdump");

    if tm_cache.exists() {
        from_dump_file(tm_cache).unwrap()
    } else {
        let theme = ThemeSet::get_theme(tm_path).unwrap();
        dump_to_file(&theme, tm_cache).unwrap();
        theme

    }
}

fn main() {
    let ss = SyntaxSet::load_defaults_newlines(); // note we load the version with newlines
    let ts = ThemeSet::load_defaults();

    let args: Vec<String> = std::env::args().collect();
    let theme;
    let theme_ref;

    if args.len() < 2 {
        println!("USAGE: ./syncat [THEME_FILE] SRC_FILE");
        println!("       ./syncat --list-file-types");
        return;

    } else if args.len() > 1 && args[1] == "--list-file-types" {
        println!("Supported file types:");

        for sd in ss.syntaxes() {
            println!("- {} (.{})", sd.name, sd.file_extensions.join(", ."));
        }

        return;

    } else if args.len() == 2 {
        theme_ref = &ts.themes["base16-ocean.dark"];

    } else {
        theme = load_theme(&args[1]);
        theme_ref = &theme;
    }

    let src = args.last().unwrap();
    let mut highlighter = HighlightFile::new(src, &ss, theme_ref).unwrap();

    // We use read_line instead of `for line in highlighter.reader.lines()` because that
    // doesn't return strings with a `\n`, and including the `\n` gets us more robust highlighting.
    // See the documentation for `SyntaxSet::load_syntaxes`.
    // It also allows re-using the line buffer, which should be a tiny bit faster.
    let mut line = String::new();
    while highlighter.reader.read_line(&mut line).unwrap() > 0 {
        {
            let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line);
            print!("{}", as_24_bit_terminal_escaped(&regions[..], true));
        }
        line.clear();
    }
}<commit_msg>syncat: Replaced theme+theme_ref with Cow.<commit_after>extern crate syntect;
use std::borrow::Cow;
use std::path::Path;
use syntect::parsing::SyntaxSet;
use syntect::highlighting::{Theme, ThemeSet, Style};
use syntect::util::as_24_bit_terminal_escaped;
use syntect::easy::HighlightFile;
use syntect::dumps::{from_dump_file, dump_to_file};

use std::io::BufRead;

fn load_theme(tm_file: &String) -> Theme {
    let tm_path = Path::new(tm_file);
    let tm_cache = tm_path.with_extension("tmdump");

    if tm_cache.exists() {
        from_dump_file(tm_cache).unwrap()
    } else {
        let theme = ThemeSet::get_theme(tm_path).unwrap();
        dump_to_file(&theme, tm_cache).unwrap();
        theme

    }
}

fn main() {
    let ss = SyntaxSet::load_defaults_newlines(); // note we load the version with newlines
    let ts = ThemeSet::load_defaults();

    let args: Vec<String> = std::env::args().collect();
    let theme;

    if args.len() < 2 {
        println!("USAGE: ./syncat [THEME_FILE] SRC_FILE");
        println!("       ./syncat --list-file-types");
        return;

    } else if args.len() > 1 && args[1] == "--list-file-types" {
        println!("Supported file types:");

        for sd in ss.syntaxes() {
            println!("- {} (.{})", sd.name, sd.file_extensions.join(", ."));
        }

        return;

    } else if args.len() == 2 {
        theme = Cow::Borrowed(&ts.themes["base16-ocean.dark"]);

    } else {
        theme = Cow::Owned(load_theme(&args[1]));
    }

    let src = args.last().unwrap();
    let mut highlighter = HighlightFile::new(src, &ss, &theme).unwrap();

    // We use read_line instead of `for line in highlighter.reader.lines()` because that
    // doesn't return strings with a `\n`, and including the `\n` gets us more robust highlighting.
    // See the documentation for `SyntaxSet::load_syntaxes`.
    // It also allows re-using the line buffer, which should be a tiny bit faster.
    let mut line = String::new();
    while highlighter.reader.read_line(&mut line).unwrap() > 0 {
        {
            let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line);
            print!("{}", as_24_bit_terminal_escaped(&regions[..], true));
        }
        line.clear();
    }
}
{'fraction_non_alphanumeric': 0.15879732739420935, 'fraction_numerical': 0.005345211581291759, 'mean_word_length': 2.9638128861429833, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2439552', 'n_tokens_mistral': 1517, 'n_tokens_neox': 1472, 'n_words': 348}