mirror of https://github.com/sharkdp/bat
Extract some private submodules from 'bat::assets' (#1850)
parent
6226eba52a
commit
e84b702309
@ -0,0 +1,42 @@
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::error::*;
|
||||
|
||||
const IGNORED_SUFFIXES: [&str; 13] = [
|
||||
// Editor etc backups
|
||||
"~",
|
||||
".bak",
|
||||
".old",
|
||||
".orig",
|
||||
// Debian and derivatives apt/dpkg/ucf backups
|
||||
".dpkg-dist",
|
||||
".dpkg-old",
|
||||
".ucf-dist",
|
||||
".ucf-new",
|
||||
".ucf-old",
|
||||
// Red Hat and derivatives rpm backups
|
||||
".rpmnew",
|
||||
".rpmorig",
|
||||
".rpmsave",
|
||||
// Build system input/template files
|
||||
".in",
|
||||
];
|
||||
|
||||
/// If we find an ignored suffix on the file name, e.g. '~', we strip it and
|
||||
/// then try again without it.
|
||||
pub fn try_with_stripped_suffix<T, F>(file_name: &OsStr, func: F) -> Result<Option<T>>
|
||||
where
|
||||
F: Fn(&OsStr) -> Result<Option<T>>,
|
||||
{
|
||||
let mut from_stripped = None;
|
||||
if let Some(file_str) = Path::new(file_name).to_str() {
|
||||
for suffix in &IGNORED_SUFFIXES {
|
||||
if let Some(stripped_filename) = file_str.strip_suffix(suffix) {
|
||||
from_stripped = func(OsStr::new(stripped_filename))?;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(from_stripped)
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use lazycell::LazyCell;
|
||||
|
||||
use syntect::parsing::SyntaxSet;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct MinimalAssets {
|
||||
minimal_syntaxes: MinimalSyntaxes,
|
||||
|
||||
/// Lazily load serialized [SyntaxSet]s from [Self.minimal_syntaxes]. The
|
||||
/// index in this vec matches the index in
|
||||
/// [Self.minimal_syntaxes.serialized_syntax_sets]
|
||||
deserialized_minimal_syntaxes: Vec<LazyCell<SyntaxSet>>,
|
||||
}
|
||||
|
||||
/// Stores and allows lookup of minimal [SyntaxSet]s. The [SyntaxSet]s are
|
||||
/// stored in serialized form, and are deserialized on-demand. This gives good
|
||||
/// startup performance since only the necessary [SyntaxReference]s needs to be
|
||||
/// deserialized.
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub(crate) struct MinimalSyntaxes {
|
||||
/// Lookup the index into `serialized_syntax_sets` of a [SyntaxSet] by the
|
||||
/// name of any [SyntaxReference] inside the [SyntaxSet]
|
||||
/// (We will later add `by_extension`, `by_first_line`, etc.)
|
||||
pub(crate) by_name: HashMap<String, usize>,
|
||||
|
||||
/// Serialized [SyntaxSet]s. Whether or not this data is compressed is
|
||||
/// decided by [COMPRESS_SERIALIZED_MINIMAL_SYNTAXES]
|
||||
pub(crate) serialized_syntax_sets: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl MinimalAssets {
|
||||
pub(crate) fn new(minimal_syntaxes: MinimalSyntaxes) -> Self {
|
||||
// Prepare so we can lazily load minimal syntaxes without a mut reference
|
||||
let deserialized_minimal_syntaxes =
|
||||
vec![LazyCell::new(); minimal_syntaxes.serialized_syntax_sets.len()];
|
||||
|
||||
Self {
|
||||
minimal_syntaxes,
|
||||
deserialized_minimal_syntaxes,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_syntax_set_by_name(&self, name: &str) -> Option<&SyntaxSet> {
|
||||
self.minimal_syntaxes
|
||||
.by_name
|
||||
.get(&name.to_ascii_lowercase())
|
||||
.and_then(|index| self.get_minimal_syntax_set_with_index(*index))
|
||||
}
|
||||
|
||||
fn load_minimal_syntax_set_with_index(&self, index: usize) -> Result<SyntaxSet> {
|
||||
let serialized_syntax_set = &self.minimal_syntaxes.serialized_syntax_sets[index];
|
||||
asset_from_contents(
|
||||
&serialized_syntax_set[..],
|
||||
&format!("minimal syntax set {}", index),
|
||||
COMPRESS_SERIALIZED_MINIMAL_SYNTAXES,
|
||||
)
|
||||
.map_err(|_| format!("Could not parse minimal syntax set {}", index).into())
|
||||
}
|
||||
|
||||
fn get_minimal_syntax_set_with_index(&self, index: usize) -> Option<&SyntaxSet> {
|
||||
self.deserialized_minimal_syntaxes
|
||||
.get(index)
|
||||
.and_then(|cell| {
|
||||
cell.try_borrow_with(|| self.load_minimal_syntax_set_with_index(index))
|
||||
.ok()
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use syntect::parsing::SyntaxSet;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// A SyntaxSet in serialized form, i.e. bincoded and flate2 compressed.
|
||||
/// We keep it in this format since we want to load it lazily.
|
||||
#[derive(Debug)]
|
||||
pub enum SerializedSyntaxSet {
|
||||
/// The data comes from a user-generated cache file.
|
||||
FromFile(PathBuf),
|
||||
|
||||
/// The data to use is embedded into the bat binary.
|
||||
FromBinary(&'static [u8]),
|
||||
}
|
||||
|
||||
impl SerializedSyntaxSet {
|
||||
pub fn deserialize(&self) -> Result<SyntaxSet> {
|
||||
match self {
|
||||
SerializedSyntaxSet::FromBinary(data) => Ok(from_binary(data, COMPRESS_SYNTAXES)),
|
||||
SerializedSyntaxSet::FromFile(ref path) => {
|
||||
asset_from_cache(path, "syntax set", COMPRESS_SYNTAXES)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue