diff --git a/Cargo.lock b/Cargo.lock index e9a5535..7347b53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,15 +240,14 @@ dependencies = [ [[package]] name = "norad" version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce992b9240bd5d664ac85340de11a3800402f7552673898e176262a59447e016" +source = "git+https://github.com/linebender/norad?branch=master#3444ad39867a053a73c6f53468eb3905201fcf19" dependencies = [ "plist", "quick-xml", - "rayon", "serde", "serde_derive", "serde_repr", + "thiserror", "uuid", ] @@ -528,6 +527,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.3.7" diff --git a/Cargo.toml b/Cargo.toml index b6e59d9..07e9831 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,8 @@ exclude = [ ] [dependencies] -norad = { version = "0.6.0", features = ["rayon"] } +# norad = { version = "0.6.0", features = ["rayon"] } +norad = { git = "https://github.com/linebender/norad", branch = "master" } structopt = "0.3" colored = "2.0" rayon = "1.5" diff --git a/src/lib/errors.rs b/src/lib/errors.rs index aee3224..a1e2f7c 100644 --- a/src/lib/errors.rs +++ b/src/lib/errors.rs @@ -15,18 +15,34 @@ lazy_static! { #[derive(Debug)] pub(crate) enum Error { InvalidPath(PathBuf), - NoradRead(PathBuf, norad::Error), - NoradWrite(PathBuf, norad::Error), + NoradRead(PathBuf, norad::error::FontLoadError), + NoradWrite(PathBuf, norad::error::FontWriteError), +} + +// Implementation adapted from https://www.lpalmieri.com/posts/error-handling-rust/ +fn chained_error_fmt( + e: &impl std::error::Error, + f: &mut std::fmt::Formatter<'_>, +) -> std::fmt::Result { + writeln!(f, "{}\n", e)?; + let mut current_err = e.source(); + while let Some(err_cause) = current_err { + writeln!(f, "Caused by:\n\t{}", err_cause)?; + current_err = err_cause.source(); + } + Ok(()) } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> { match &self { Error::NoradRead(p, e) => { - write!(f, "norad read error: {}: {}", p.display(), e) + writeln!(f, "norad read error: {}", p.display())?; + chained_error_fmt(e, f) } Error::NoradWrite(p, e) => { - write!(f, "norad write error: {}: {}", p.display(), e) + writeln!(f, "norad write error: {}", p.display())?; + chained_error_fmt(e, f) } Error::InvalidPath(p) => { write!(f, "invalid path error: {} was not found", p.display()) @@ -49,14 +65,14 @@ mod tests { #[test] fn test_ufofmterror_read() { - let ne = norad::Error::MissingLayer("test".to_owned()); + let ne = norad::error::FontLoadError::MissingDefaultLayer; let ufe = Error::NoradRead(PathBuf::from("test.ufo"), ne); assert!(ufe.to_string().starts_with("norad read error: ")); } #[test] fn test_ufofmterror_write() { - let ne = norad::Error::MissingLayer("test".to_owned()); + let ne = norad::error::FontWriteError::PreexistingPublicObjectLibsKey; let ufe = Error::NoradWrite(PathBuf::from("test.ufo"), ne); assert!(ufe.to_string().starts_with("norad write error: ")); }