on master help sign in
Extract some private submodules from 'bat::assets' (#1850)
commite84b702309471e31621cf0bc06f8754511a5cbbc authorMartin Nordholts <enselic@gmail.com> dateWed 15 Sep 2021, 07:59 (5 years ago) parent6226eba
7 files changed+166−126
src/assets.rs+21−121 src/assets_metadata.rs → src/assets/assets_metadata.rs src/build_assets.rs → src/assets/build_assets.rs+1−2 src/assets/ignored_suffixes.rs+42 src/assets/minimal_assets.rs+72 src/assets/serialized_syntax_set.rs+27 src/lib.rs+3−3
src/assets.rs+21−121
@@ -1,7 +1,6 @@
1−use std::collections::HashMap;
21use std::ffi::OsStr;
32use std::fs;
4−use std::path::{Path, PathBuf};
3+use std::path::Path;
54
65use lazycell::LazyCell;
76
@@ -15,17 +14,26 @@ use crate::error::*;
1514use crate::input::{InputReader, OpenedInput, OpenedInputKind};
1615use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
1716
17+use ignored_suffixes::*;
18+use minimal_assets::*;
19+use serialized_syntax_set::*;
20+
21+#[cfg(feature = "build-assets")]
22+pub use crate::assets::build_assets::*;
23+
24+pub(crate) mod assets_metadata;
25+#[cfg(feature = "build-assets")]
26+mod build_assets;
27+mod ignored_suffixes;
28+mod minimal_assets;
29+mod serialized_syntax_set;
30+
1831#[derive(Debug)]
1932pub struct HighlightingAssets {
2033 syntax_set_cell: LazyCell<SyntaxSet>,
2134 serialized_syntax_set: SerializedSyntaxSet,
2235
23− minimal_syntaxes: MinimalSyntaxes,
24−
25− /// Lazily load serialized [SyntaxSet]s from [Self.minimal_syntaxes]. The
26− /// index in this vec matches the index in
27− /// [Self.minimal_syntaxes.serialized_syntax_sets]
28− deserialized_minimal_syntaxes: Vec<LazyCell<SyntaxSet>>,
36+ minimal_assets: MinimalAssets,
2937
3038 theme_set: ThemeSet,
3139 fallback_theme: Option<&'static str>,
@@ -37,22 +45,6 @@ pub struct SyntaxReferenceInSet<'a> {
3745 pub syntax_set: &'a SyntaxSet,
3846}
3947
40−/// Stores and allows lookup of minimal [SyntaxSet]s. The [SyntaxSet]s are
41−/// stored in serialized form, and are deserialized on-demand. This gives good
42−/// startup performance since only the necessary [SyntaxReference]s needs to be
43−/// deserialized.
44−#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
45−pub(crate) struct MinimalSyntaxes {
46− /// Lookup the index into `serialized_syntax_sets` of a [SyntaxSet] by the
47− /// name of any [SyntaxReference] inside the [SyntaxSet]
48− /// (We will later add `by_extension`, `by_first_line`, etc.)
49− pub(crate) by_name: HashMap<String, usize>,
50−
51− /// Serialized [SyntaxSet]s. Whether or not this data is compressed is
52− /// decided by [COMPRESS_SERIALIZED_MINIMAL_SYNTAXES]
53− pub(crate) serialized_syntax_sets: Vec<Vec<u8>>,
54−}
55−
5648// Compress for size of ~700 kB instead of ~4600 kB at the cost of ~30% longer deserialization time
5749pub(crate) const COMPRESS_SYNTAXES: bool = true;
5850
@@ -70,41 +62,16 @@ pub(crate) const COMPRESS_SERIALIZED_MINIMAL_SYNTAXES: bool = true;
7062// efficient byte-by-byte copy of `serialized_syntax_sets`.
7163pub(crate) const COMPRESS_MINIMAL_SYNTAXES: bool = false;
7264
73−const IGNORED_SUFFIXES: [&str; 13] = [
74− // Editor etc backups
75− "~",
76− ".bak",
77− ".old",
78− ".orig",
79− // Debian and derivatives apt/dpkg/ucf backups
80− ".dpkg-dist",
81− ".dpkg-old",
82− ".ucf-dist",
83− ".ucf-new",
84− ".ucf-old",
85− // Red Hat and derivatives rpm backups
86− ".rpmnew",
87− ".rpmorig",
88− ".rpmsave",
89− // Build system input/template files
90− ".in",
91−];
92−
9365impl HighlightingAssets {
9466 fn new(
9567 serialized_syntax_set: SerializedSyntaxSet,
9668 minimal_syntaxes: MinimalSyntaxes,
9769 theme_set: ThemeSet,
9870 ) -> Self {
99− // Prepare so we can lazily load minimal syntaxes without a mut reference
100− let deserialized_minimal_syntaxes =
101− vec![LazyCell::new(); minimal_syntaxes.serialized_syntax_sets.len()];
102−
10371 HighlightingAssets {
10472 syntax_set_cell: LazyCell::new(),
10573 serialized_syntax_set,
106− deserialized_minimal_syntaxes,
107− minimal_syntaxes,
74+ minimal_assets: MinimalAssets::new(minimal_syntaxes),
10875 theme_set,
10976 fallback_theme: None,
11077 }
@@ -167,37 +134,12 @@ impl HighlightingAssets {
167134 /// tries to find a minimal [SyntaxSet]. If none is found, returns the
168135 /// [SyntaxSet] that contains all syntaxes.
169136 fn get_syntax_set_by_name(&self, name: &str) -> Result<&SyntaxSet> {
170− let minimal_syntax_set = self
171− .minimal_syntaxes
172− .by_name
173− .get(&name.to_ascii_lowercase())
174− .and_then(|index| self.get_minimal_syntax_set_with_index(*index));
175−
176− match minimal_syntax_set {
137+ match self.minimal_assets.get_syntax_set_by_name(name) {
177138 Some(syntax_set) => Ok(syntax_set),
178139 None => self.get_syntax_set(),
179140 }
180141 }
181142
182− fn load_minimal_syntax_set_with_index(&self, index: usize) -> Result<SyntaxSet> {
183− let serialized_syntax_set = &self.minimal_syntaxes.serialized_syntax_sets[index];
184− asset_from_contents(
185− &serialized_syntax_set[..],
186− &format!("minimal syntax set {}", index),
187− COMPRESS_SERIALIZED_MINIMAL_SYNTAXES,
188− )
189− .map_err(|_| format!("Could not parse minimal syntax set {}", index).into())
190− }
191−
192− fn get_minimal_syntax_set_with_index(&self, index: usize) -> Option<&SyntaxSet> {
193− self.deserialized_minimal_syntaxes
194− .get(index)
195− .and_then(|cell| {
196− cell.try_borrow_with(|| self.load_minimal_syntax_set_with_index(index))
197− .ok()
198− })
199− }
200−
201143 /// Use [Self::get_syntax_for_file_name] instead
202144 #[deprecated]
203145 pub fn syntax_for_file_name(
@@ -319,7 +261,9 @@ impl HighlightingAssets {
319261 syntax = self.find_syntax_by_file_name_extension(file_name)?;
320262 }
321263 if syntax.is_none() {
322− syntax = self.get_extension_syntax_with_stripped_suffix(file_name)?;
264+ syntax = try_with_stripped_suffix(file_name, |stripped_file_name| {
265+ self.get_extension_syntax(stripped_file_name) // Note: recursion
266+ })?;
323267 }
324268 Ok(syntax)
325269 }
@@ -340,25 +284,6 @@ impl HighlightingAssets {
340284 )
341285 }
342286
343− /// If we find an ignored suffix on the file name, e.g. '~', we strip it and
344− /// then try again to find a syntax without it. Note that we do this recursively.
345− fn get_extension_syntax_with_stripped_suffix(
346− &self,
347− file_name: &OsStr,
348− ) -> Result<Option<SyntaxReferenceInSet>> {
349− let file_path = Path::new(file_name);
350− let mut syntax = None;
351− if let Some(file_str) = file_path.to_str() {
352− for suffix in &IGNORED_SUFFIXES {
353− if let Some(stripped_filename) = file_str.strip_suffix(suffix) {
354− syntax = self.get_extension_syntax(OsStr::new(stripped_filename))?;
355− break;
356− }
357− }
358− }
359− Ok(syntax)
360− }
361−
362287 fn get_first_line_syntax(
363288 &self,
364289 reader: &mut InputReader,
@@ -371,31 +296,6 @@ impl HighlightingAssets {
371296 }
372297}
373298
374−#[cfg(feature = "build-assets")]
375−pub use crate::build_assets::build_assets as build;
376−
377−/// A SyntaxSet in serialized form, i.e. bincoded and flate2 compressed.
378−/// We keep it in this format since we want to load it lazily.
379−#[derive(Debug)]
380−enum SerializedSyntaxSet {
381− /// The data comes from a user-generated cache file.
382− FromFile(PathBuf),
383−
384− /// The data to use is embedded into the bat binary.
385− FromBinary(&'static [u8]),
386−}
387−
388−impl SerializedSyntaxSet {
389− fn deserialize(&self) -> Result<SyntaxSet> {
390− match self {
391− SerializedSyntaxSet::FromBinary(data) => Ok(from_binary(data, COMPRESS_SYNTAXES)),
392− SerializedSyntaxSet::FromFile(ref path) => {
393− asset_from_cache(path, "syntax set", COMPRESS_SYNTAXES)
394− }
395− }
396− }
397−}
398−
399299pub(crate) fn get_serialized_integrated_syntaxset() -> &'static [u8] {
400300 include_bytes!("../assets/syntaxes.bin")
401301}
src/assets_metadata.rs → src/assets/assets_metadata.rsrenamed

The content is the same.

src/build_assets.rs → src/assets/build_assets.rsrenamed+1−2
@@ -7,7 +7,6 @@ use syntect::parsing::syntax_definition::{
77use syntect::parsing::{Scope, SyntaxSet, SyntaxSetBuilder};
88
99use crate::assets::*;
10−use crate::error::*;
1110
1211type SyntaxName = String;
1312
@@ -27,7 +26,7 @@ enum Dependency {
2726 ByScope(Scope),
2827}
2928
30−pub fn build_assets(
29+pub fn build(
3130 source_dir: &Path,
3231 include_integrated_assets: bool,
3332 target_dir: &Path,
src/assets/ignored_suffixes.rsnew file+42
@@ -0,0 +1,42 @@
1+use std::ffi::OsStr;
2+use std::path::Path;
3+
4+use crate::error::*;
5+
6+const IGNORED_SUFFIXES: [&str; 13] = [
7+ // Editor etc backups
8+ "~",
9+ ".bak",
10+ ".old",
11+ ".orig",
12+ // Debian and derivatives apt/dpkg/ucf backups
13+ ".dpkg-dist",
14+ ".dpkg-old",
15+ ".ucf-dist",
16+ ".ucf-new",
17+ ".ucf-old",
18+ // Red Hat and derivatives rpm backups
19+ ".rpmnew",
20+ ".rpmorig",
21+ ".rpmsave",
22+ // Build system input/template files
23+ ".in",
24+];
25+
26+/// If we find an ignored suffix on the file name, e.g. '~', we strip it and
27+/// then try again without it.
28+pub fn try_with_stripped_suffix<T, F>(file_name: &OsStr, func: F) -> Result<Option<T>>
29+where
30+ F: Fn(&OsStr) -> Result<Option<T>>,
31+{
32+ let mut from_stripped = None;
33+ if let Some(file_str) = Path::new(file_name).to_str() {
34+ for suffix in &IGNORED_SUFFIXES {
35+ if let Some(stripped_filename) = file_str.strip_suffix(suffix) {
36+ from_stripped = func(OsStr::new(stripped_filename))?;
37+ break;
38+ }
39+ }
40+ }
41+ Ok(from_stripped)
42+}
src/assets/minimal_assets.rsnew file+72
@@ -0,0 +1,72 @@
1+use std::collections::HashMap;
2+
3+use lazycell::LazyCell;
4+
5+use syntect::parsing::SyntaxSet;
6+
7+use super::*;
8+
9+#[derive(Debug)]
10+pub(crate) struct MinimalAssets {
11+ minimal_syntaxes: MinimalSyntaxes,
12+
13+ /// Lazily load serialized [SyntaxSet]s from [Self.minimal_syntaxes]. The
14+ /// index in this vec matches the index in
15+ /// [Self.minimal_syntaxes.serialized_syntax_sets]
16+ deserialized_minimal_syntaxes: Vec<LazyCell<SyntaxSet>>,
17+}
18+
19+/// Stores and allows lookup of minimal [SyntaxSet]s. The [SyntaxSet]s are
20+/// stored in serialized form, and are deserialized on-demand. This gives good
21+/// startup performance since only the necessary [SyntaxReference]s needs to be
22+/// deserialized.
23+#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
24+pub(crate) struct MinimalSyntaxes {
25+ /// Lookup the index into `serialized_syntax_sets` of a [SyntaxSet] by the
26+ /// name of any [SyntaxReference] inside the [SyntaxSet]
27+ /// (We will later add `by_extension`, `by_first_line`, etc.)
28+ pub(crate) by_name: HashMap<String, usize>,
29+
30+ /// Serialized [SyntaxSet]s. Whether or not this data is compressed is
31+ /// decided by [COMPRESS_SERIALIZED_MINIMAL_SYNTAXES]
32+ pub(crate) serialized_syntax_sets: Vec<Vec<u8>>,
33+}
34+
35+impl MinimalAssets {
36+ pub(crate) fn new(minimal_syntaxes: MinimalSyntaxes) -> Self {
37+ // Prepare so we can lazily load minimal syntaxes without a mut reference
38+ let deserialized_minimal_syntaxes =
39+ vec![LazyCell::new(); minimal_syntaxes.serialized_syntax_sets.len()];
40+
41+ Self {
42+ minimal_syntaxes,
43+ deserialized_minimal_syntaxes,
44+ }
45+ }
46+
47+ pub fn get_syntax_set_by_name(&self, name: &str) -> Option<&SyntaxSet> {
48+ self.minimal_syntaxes
49+ .by_name
50+ .get(&name.to_ascii_lowercase())
51+ .and_then(|index| self.get_minimal_syntax_set_with_index(*index))
52+ }
53+
54+ fn load_minimal_syntax_set_with_index(&self, index: usize) -> Result<SyntaxSet> {
55+ let serialized_syntax_set = &self.minimal_syntaxes.serialized_syntax_sets[index];
56+ asset_from_contents(
57+ &serialized_syntax_set[..],
58+ &format!("minimal syntax set {}", index),
59+ COMPRESS_SERIALIZED_MINIMAL_SYNTAXES,
60+ )
61+ .map_err(|_| format!("Could not parse minimal syntax set {}", index).into())
62+ }
63+
64+ fn get_minimal_syntax_set_with_index(&self, index: usize) -> Option<&SyntaxSet> {
65+ self.deserialized_minimal_syntaxes
66+ .get(index)
67+ .and_then(|cell| {
68+ cell.try_borrow_with(|| self.load_minimal_syntax_set_with_index(index))
69+ .ok()
70+ })
71+ }
72+}
src/assets/serialized_syntax_set.rsnew file+27
@@ -0,0 +1,27 @@
1+use std::path::PathBuf;
2+
3+use syntect::parsing::SyntaxSet;
4+
5+use super::*;
6+
7+/// A SyntaxSet in serialized form, i.e. bincoded and flate2 compressed.
8+/// We keep it in this format since we want to load it lazily.
9+#[derive(Debug)]
10+pub enum SerializedSyntaxSet {
11+ /// The data comes from a user-generated cache file.
12+ FromFile(PathBuf),
13+
14+ /// The data to use is embedded into the bat binary.
15+ FromBinary(&'static [u8]),
16+}
17+
18+impl SerializedSyntaxSet {
19+ pub fn deserialize(&self) -> Result<SyntaxSet> {
20+ match self {
21+ SerializedSyntaxSet::FromBinary(data) => Ok(from_binary(data, COMPRESS_SYNTAXES)),
22+ SerializedSyntaxSet::FromFile(ref path) => {
23+ asset_from_cache(path, "syntax set", COMPRESS_SYNTAXES)
24+ }
25+ }
26+ }
27+}
src/lib.rs+3−3
@@ -22,9 +22,9 @@
2222mod macros;
2323
2424pub mod assets;
25−pub mod assets_metadata;
26−#[cfg(feature = "build-assets")]
27−mod build_assets;
25+pub mod assets_metadata {
26+ pub use super::assets::assets_metadata::*;
27+}
2828pub mod config;
2929pub mod controller;
3030mod decorations;