summaryrefslogtreecommitdiff
path: root/src/loading
diff options
context:
space:
mode:
Diffstat (limited to 'src/loading')
-rw-r--r--src/loading/fs.rs24
-rw-r--r--src/loading/mod.rs18
2 files changed, 32 insertions, 10 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)]
diff --git a/src/loading/mod.rs b/src/loading/mod.rs
index 818e7e3c..b4e5d160 100644
--- a/src/loading/mod.rs
+++ b/src/loading/mod.rs
@@ -6,6 +6,7 @@ mod fs;
#[cfg(feature = "fs")]
pub use fs::*;
+use std::path::Path;
use std::rc::Rc;
use crate::font::FaceInfo;
@@ -18,13 +19,22 @@ pub trait Loader {
/// Descriptions of all font faces this loader serves.
fn faces(&self) -> &[FaceInfo];
+ /// Resolve a hash that is the same for all paths pointing to the same file.
+ ///
+ /// Should return `None` if the file does not exist.
+ fn resolve(&self, path: &Path) -> Option<FileHash>;
+
/// Load the font face with the given index in [`faces()`](Self::faces).
fn load_face(&mut self, idx: usize) -> Option<Buffer>;
/// Load a file from a path.
- fn load_file(&mut self, path: &str) -> Option<Buffer>;
+ fn load_file(&mut self, path: &Path) -> Option<Buffer>;
}
+/// A hash that must be the same for all paths pointing to the same file.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct FileHash(pub u64);
+
/// A loader which serves nothing.
pub struct BlankLoader;
@@ -33,11 +43,15 @@ impl Loader for BlankLoader {
&[]
}
+ fn resolve(&self, _: &Path) -> Option<FileHash> {
+ None
+ }
+
fn load_face(&mut self, _: usize) -> Option<Buffer> {
None
}
- fn load_file(&mut self, _: &str) -> Option<Buffer> {
+ fn load_file(&mut self, _: &Path) -> Option<Buffer> {
None
}
}