From 6aff395a5d016ce9bcbe88a65f639cf5f922ed28 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 24 Oct 2023 11:34:12 +0200 Subject: [PATCH 1/2] Use `eyre` for error handling `Box` is not `Send`, which makes it harder to parallelize the rendering of the blog posts. `eyre::Report` fortunately does not have this problem. --- Cargo.lock | 17 +++++++++++++++++ Cargo.toml | 1 + src/blog.rs | 4 +--- src/blogs.rs | 7 +++---- src/lib.rs | 21 ++++++++++----------- src/posts.rs | 6 +++--- 6 files changed, 35 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19ad53230..92c8d842f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,6 +100,7 @@ version = "0.1.0" dependencies = [ "chrono", "comrak", + "eyre", "handlebars", "lazy_static", "regex", @@ -282,6 +283,16 @@ dependencies = [ "termcolor", ] +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fake-simd" version = "0.1.2" @@ -559,6 +570,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + [[package]] name = "indexmap" version = "1.9.1" diff --git a/Cargo.toml b/Cargo.toml index 6325f08a6..44173fd20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ name = "blog" path = "src/blog.rs" [dependencies] +eyre = "0.6.8" handlebars = { version = "3", features = ["dir_source"] } lazy_static = "1.4.0" serde = "1.0" diff --git a/src/blog.rs b/src/blog.rs index 17442c65e..2b5ef3d14 100644 --- a/src/blog.rs +++ b/src/blog.rs @@ -1,9 +1,7 @@ -use std::error::Error; - #[path = "lib.rs"] mod lib; -pub fn main() -> Result<(), Box> { +pub fn main() -> eyre::Result<()> { lib::main()?; println!("blog has been generated; you can now serve its content by running\n\ diff --git a/src/blogs.rs b/src/blogs.rs index 2ee8e9dd0..b76f70454 100644 --- a/src/blogs.rs +++ b/src/blogs.rs @@ -1,6 +1,5 @@ use super::posts::Post; use serde_derive::{Deserialize, Serialize}; -use std::error::Error; use std::path::{Path, PathBuf}; static MANIFEST_FILE: &str = "blog.yml"; @@ -46,7 +45,7 @@ pub(crate) struct Blog { } impl Blog { - fn load(prefix: PathBuf, dir: &Path) -> Result> { + fn load(prefix: PathBuf, dir: &Path) -> eyre::Result { let manifest_content = std::fs::read_to_string(dir.join(MANIFEST_FILE))?; let manifest: Manifest = serde_yaml::from_str(&manifest_content)?; @@ -122,7 +121,7 @@ impl Blog { /// Recursively load blogs in a directory. A blog is a directory with a `blog.yml` /// file inside it. -pub(crate) fn load(base: &Path) -> Result, Box> { +pub(crate) fn load(base: &Path) -> eyre::Result> { let mut blogs = Vec::new(); load_recursive(base, base, &mut blogs)?; Ok(blogs) @@ -132,7 +131,7 @@ fn load_recursive( base: &Path, current: &Path, blogs: &mut Vec, -) -> Result<(), Box> { +) -> eyre::Result<()> { for entry in std::fs::read_dir(current)? { let path = entry?.path(); let file_type = path.metadata()?.file_type(); diff --git a/src/lib.rs b/src/lib.rs index e77f632d6..c0a048bc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,6 @@ use sass_rs::{compile_file, Options}; use serde_derive::Serialize; use serde_json::json; use std::convert::AsRef; -use std::error::Error; use std::fs::{self, File}; use std::io::{self, Write}; use std::path::{Path, PathBuf}; @@ -51,7 +50,7 @@ impl<'a> Generator<'a> { fn new( out_directory: impl AsRef, posts_directory: impl AsRef, - ) -> Result> { + ) -> eyre::Result { let mut handlebars = Handlebars::new(); handlebars.set_strict_mode(true); handlebars.register_templates_directory(".hbs", "templates")?; @@ -80,7 +79,7 @@ impl<'a> Generator<'a> { .replace(std::path::MAIN_SEPARATOR, "/") } - fn render(&self) -> Result<(), Box> { + fn render(&self) -> eyre::Result<()> { // make sure our output directory exists fs::create_dir_all(&self.out_directory)?; @@ -116,7 +115,7 @@ impl<'a> Generator<'a> { fs::write("./static/styles/vendor.css", &concatted).expect("couldn't write vendor css"); } - fn render_blog(&self, blog: &Blog) -> Result<(), Box> { + fn render_blog(&self, blog: &Blog) -> eyre::Result<()> { std::fs::create_dir_all(self.out_directory.join(blog.prefix()))?; let path = self.render_index(blog)?; @@ -136,7 +135,7 @@ impl<'a> Generator<'a> { Ok(()) } - fn render_index(&self, blog: &Blog) -> Result> { + fn render_index(&self, blog: &Blog) -> eyre::Result { let other_blogs: Vec<_> = self .blogs .iter() @@ -161,7 +160,7 @@ impl<'a> Generator<'a> { Ok(path) } - fn render_post(&self, blog: &Blog, post: &Post) -> Result> { + fn render_post(&self, blog: &Blog, post: &Post) -> eyre::Result { let path = blog .prefix() .join(format!("{:04}", &post.year)) @@ -186,7 +185,7 @@ impl<'a> Generator<'a> { Ok(path) } - fn render_feed(&self, blog: &Blog) -> Result<(), Box> { + fn render_feed(&self, blog: &Blog) -> eyre::Result<()> { let posts: Vec<_> = blog.posts().iter().take(10).collect(); let data = json!({ "blog": blog, @@ -198,7 +197,7 @@ impl<'a> Generator<'a> { Ok(()) } - fn render_releases_feed(&self, blog: &Blog) -> Result<(), Box> { + fn render_releases_feed(&self, blog: &Blog) -> eyre::Result<()> { let posts = blog.posts().iter().cloned().collect::>(); let is_released: Vec<&Post> = posts.iter().filter(|post| post.release).collect(); let releases: Vec = is_released @@ -223,7 +222,7 @@ impl<'a> Generator<'a> { Ok(()) } - fn copy_static_files(&self) -> Result<(), Box> { + fn copy_static_files(&self) -> eyre::Result<()> { copy_dir("static/fonts", &self.out_directory)?; copy_dir("static/images", &self.out_directory)?; copy_dir("static/styles", &self.out_directory)?; @@ -236,7 +235,7 @@ impl<'a> Generator<'a> { name: impl AsRef, template: &str, data: serde_json::Value, - ) -> Result<(), Box> { + ) -> eyre::Result<()> { let out_file = self.out_directory.join(name.as_ref()); let file = File::create(out_file)?; self.handlebars.render_to_write(template, &data, file)?; @@ -264,7 +263,7 @@ fn copy_dir(source: impl AsRef, dest: impl AsRef) -> Result<(), io:: copy_inner(source, &dest) } -pub fn main() -> Result<(), Box> { +pub fn main() -> eyre::Result<()> { let blog = Generator::new("site", "posts")?; blog.render()?; diff --git a/src/posts.rs b/src/posts.rs index 3b330cfac..1e5f459cb 100644 --- a/src/posts.rs +++ b/src/posts.rs @@ -2,8 +2,8 @@ use super::blogs::Manifest; use comrak::{ComrakExtensionOptions, ComrakOptions, ComrakRenderOptions}; use regex::Regex; use serde_derive::{Deserialize, Serialize}; -use std::error::Error; use std::path::{Path, PathBuf}; +use eyre::eyre; #[derive(Debug, PartialEq, Deserialize)] struct YamlHeader { @@ -36,7 +36,7 @@ pub(crate) struct Post { } impl Post { - pub(crate) fn open(path: &Path, manifest: &Manifest) -> Result> { + pub(crate) fn open(path: &Path, manifest: &Manifest) -> eyre::Result { // yeah this might blow up, but it won't let filename = path.file_name().unwrap().to_str().unwrap(); @@ -52,7 +52,7 @@ impl Post { let contents = std::fs::read_to_string(path)?; if contents.len() < 5 { return Err( - format!("{path:?} is empty, or too short to have valid front matter").into(), + eyre!("{path:?} is empty, or too short to have valid front matter") ); } From 10d0287f454901b73854f94af1d0b87b9b94ea82 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 24 Oct 2023 11:56:29 +0200 Subject: [PATCH 2/2] Use `color-eyre` for error reporting --- Cargo.lock | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 1 + src/blog.rs | 2 + 3 files changed, 141 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92c8d842f..dd0284f91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -43,6 +52,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide 0.7.1", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.0" @@ -99,6 +123,7 @@ name = "blog" version = "0.1.0" dependencies = [ "chrono", + "color-eyre", "comrak", "eyre", "handlebars", @@ -191,6 +216,33 @@ dependencies = [ "vec_map", ] +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + [[package]] name = "comrak" version = "0.13.0" @@ -315,7 +367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.5.3", ] [[package]] @@ -406,6 +458,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "h2" version = "0.3.17" @@ -630,9 +688,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "line-wrap" @@ -707,6 +765,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.7.14" @@ -794,6 +861,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.13.0" @@ -828,6 +904,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + [[package]] name = "pem" version = "1.1.0" @@ -1090,6 +1172,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustls" version = "0.20.8" @@ -1254,6 +1342,15 @@ dependencies = [ "digest 0.10.3", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shell-words" version = "1.0.0" @@ -1409,6 +1506,16 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.1.43" @@ -1559,6 +1666,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", ] [[package]] @@ -1701,6 +1830,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vec_map" version = "0.8.1" diff --git a/Cargo.toml b/Cargo.toml index 44173fd20..e3bbcb7ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ name = "blog" path = "src/blog.rs" [dependencies] +color-eyre = "0.6.2" eyre = "0.6.8" handlebars = { version = "3", features = ["dir_source"] } lazy_static = "1.4.0" diff --git a/src/blog.rs b/src/blog.rs index 2b5ef3d14..2ad10b925 100644 --- a/src/blog.rs +++ b/src/blog.rs @@ -2,6 +2,8 @@ mod lib; pub fn main() -> eyre::Result<()> { + color_eyre::install()?; + lib::main()?; println!("blog has been generated; you can now serve its content by running\n\