diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 9ec33b131..34986ffa9 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -86,7 +86,7 @@ impl<'a> EvalContext<'a> { /// Generates an error if the file is not found. pub fn resolve(&mut self, path: &str, span: Span) -> Option { let base = *self.route.last()?; - self.loader.resolve_from(base, Path::new(path)).or_else(|| { + self.loader.resolve_from(base, Path::new(path)).ok().or_else(|| { self.diag(error!(span, "file not found")); None }) @@ -107,7 +107,7 @@ impl<'a> EvalContext<'a> { return Some(id); } - let buffer = self.loader.load_file(id).or_else(|| { + let buffer = self.loader.load_file(id).ok().or_else(|| { self.diag(error!(span, "failed to load file")); None })?; diff --git a/src/font.rs b/src/font.rs index 0d6cd8809..93c21441b 100644 --- a/src/font.rs +++ b/src/font.rs @@ -281,7 +281,7 @@ impl FontCache { let buffer = match self.buffers.entry(file) { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { - let buffer = self.loader.load_file(file)?; + let buffer = self.loader.load_file(file).ok()?; entry.insert(Rc::new(buffer)) } }; diff --git a/src/image.rs b/src/image.rs index d0719ac78..5738be5fc 100644 --- a/src/image.rs +++ b/src/image.rs @@ -74,7 +74,7 @@ impl ImageCache { pub fn load(&mut self, file: FileId) -> Option { let id = ImageId(file.into_raw()); if let Entry::Vacant(entry) = self.images.entry(id) { - let buffer = self.loader.load_file(file)?; + let buffer = self.loader.load_file(file).ok()?; let image = Image::parse(&buffer)?; if let Some(callback) = &self.on_load { callback(id, &image); diff --git a/src/loading/fs.rs b/src/loading/fs.rs index 407e2d94f..0f6f1076c 100644 --- a/src/loading/fs.rs +++ b/src/loading/fs.rs @@ -187,13 +187,16 @@ impl Loader for FsLoader { &self.faces } - fn resolve_from(&self, base: FileId, path: &Path) -> Option { - let full = self.paths.borrow()[&base].parent()?.join(path); - self.resolve(&full).ok() + fn resolve_from(&self, base: FileId, path: &Path) -> io::Result { + let full = self.paths.borrow()[&base] + .parent() + .expect("base is a file") + .join(path); + self.resolve(&full) } - fn load_file(&self, id: FileId) -> Option> { - fs::read(&self.paths.borrow()[&id]).ok() + fn load_file(&self, id: FileId) -> io::Result> { + fs::read(&self.paths.borrow()[&id]) } } diff --git a/src/loading/mod.rs b/src/loading/mod.rs index 3be74428a..64a65580b 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::io; use std::path::Path; use serde::{Deserialize, Serialize}; @@ -21,10 +22,13 @@ pub trait Loader { /// /// This should return the same id for all paths pointing to the same file /// and `None` if the file does not exist. - fn resolve_from(&self, base: FileId, path: &Path) -> Option; + fn resolve_from(&self, base: FileId, path: &Path) -> io::Result; /// Load a file by id. - fn load_file(&self, id: FileId) -> Option>; + /// + /// This must only be called with an `id` returned by a call to this + /// loader's `resolve_from` method. + fn load_file(&self, id: FileId) -> io::Result>; } /// A file id that can be [resolved](Loader::resolve_from) from a path. @@ -53,11 +57,11 @@ impl Loader for BlankLoader { &[] } - fn resolve_from(&self, _: FileId, _: &Path) -> Option { - None + fn resolve_from(&self, _: FileId, _: &Path) -> io::Result { + Err(io::ErrorKind::NotFound.into()) } - fn load_file(&self, _: FileId) -> Option> { - None + fn load_file(&self, _: FileId) -> io::Result> { + panic!("resolve_from never returns an id") } }