summaryrefslogtreecommitdiff
path: root/src/loading/fs.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-05-29 15:45:57 +0200
committerLaurenz <laurmaedje@gmail.com>2021-05-31 22:33:40 +0200
commite023bf2ac9f5796355d9485afc16781196bf212b (patch)
tree26d4487de0c4e2d0f69182483301de867cb5fa34 /src/loading/fs.rs
parent9f77f09aacd1fb0fd6138a6d16ed2755f6bfae3f (diff)
Module loading system
Detects cyclic imports and loads each module only once per compilation.
Diffstat (limited to 'src/loading/fs.rs')
-rw-r--r--src/loading/fs.rs24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/loading/fs.rs b/src/loading/fs.rs
index 969ee9e0..bf768bd5 100644
--- a/src/loading/fs.rs
+++ b/src/loading/fs.rs
@@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use ttf_parser::{name_id, Face};
use walkdir::WalkDir;
-use super::{Buffer, Loader};
+use super::{Buffer, FileHash, Loader};
use crate::font::{FaceInfo, FontStretch, FontStyle, FontVariant, FontWeight};
/// Loads fonts and images from the local file system.
@@ -25,7 +25,7 @@ pub struct FsLoader {
/// Maps from paths to loaded file buffers. When the buffer is `None` the file
/// does not exist or couldn't be read.
-type FileCache = HashMap<PathBuf, Option<Buffer>>;
+type FileCache = HashMap<FileHash, Buffer>;
impl FsLoader {
/// Create a new loader without any fonts.
@@ -167,24 +167,32 @@ impl Loader for FsLoader {
&self.faces
}
+ fn resolve(&self, path: &Path) -> Option<FileHash> {
+ hash(path)
+ }
+
fn load_face(&mut self, idx: usize) -> Option<Buffer> {
load(&mut self.cache, &self.files[idx])
}
- fn load_file(&mut self, path: &str) -> Option<Buffer> {
- load(&mut self.cache, Path::new(path))
+ fn load_file(&mut self, path: &Path) -> Option<Buffer> {
+ load(&mut self.cache, path)
}
}
/// Load from the file system using a cache.
fn load(cache: &mut FileCache, path: &Path) -> Option<Buffer> {
- match cache.entry(path.to_owned()) {
+ Some(match cache.entry(hash(path)?) {
Entry::Occupied(entry) => entry.get().clone(),
Entry::Vacant(entry) => {
- let buffer = std::fs::read(path).ok().map(Rc::new);
- entry.insert(buffer).clone()
+ let buffer = std::fs::read(path).ok()?;
+ entry.insert(Rc::new(buffer)).clone()
}
- }
+ })
+}
+
+fn hash(path: &Path) -> Option<FileHash> {
+ path.canonicalize().ok().map(|p| FileHash(fxhash::hash64(&p)))
}
#[cfg(test)]