diff --git a/Cargo.lock b/Cargo.lock index 746d482..a861769 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,15 +180,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "caseless" @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.10" +version = "1.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2" dependencies = [ "shlex", ] @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -428,6 +428,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "estimated_read_time" version = "1.0.0" @@ -532,6 +538,12 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "http" version = "1.2.0" @@ -568,9 +580,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" [[package]] name = "httpdate" @@ -580,9 +592,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.5.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", "futures-channel", @@ -681,6 +693,16 @@ dependencies = [ "syn", ] +[[package]] +name = "indexmap" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + [[package]] name = "isabelroses-website" version = "0.3.0" @@ -693,10 +715,10 @@ dependencies = [ "estimated_read_time", "lazy_static", "mime_guess", - "nom", "rust-embed", "serde", "serde_json", + "serde_norway", "tera", "tokio", ] @@ -749,7 +771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" dependencies = [ "core2", - "hashbrown", + "hashbrown 0.14.5", "rle-decode-fast", ] @@ -787,12 +809,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.3" @@ -819,16 +835,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -849,9 +855,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "percent-encoding" @@ -1029,9 +1035,9 @@ checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "same-file" @@ -1064,9 +1070,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.137" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", @@ -1074,6 +1080,19 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_norway" +version = "0.9.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e408f29489b5fd500fab51ff1484fc859bb655f32c671f307dcd733b72e8168c" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml-norway", +] + [[package]] name = "serde_path_to_error" version = "0.1.16" @@ -1147,9 +1166,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.96" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -1363,9 +1382,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "unicode-normalization" @@ -1382,6 +1401,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +[[package]] +name = "unsafe-libyaml-norway" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39abd59bf32521c7f2301b52d05a6a2c975b6003521cbd0c6dc1582f0a22104" + [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index 04c7a8d..cd706c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,11 +13,11 @@ comrak = { version = "0.35.0", default-features = false } dotenv = "0.15.0" lazy_static = "1.5.0" mime_guess = "2.0.5" -nom = "7.1.3" atom_syndication = "0.12.5" rust-embed = { version = "8.5.0", features = ["include-exclude", "compression"] } serde = { version = "1.0.132", features = ["derive"] } serde_json = "1.0.132" +serde_norway = "0.9.42" tera = { version = "1.20.0", default-features = false } tokio = { version = "1.43.0", features = ["rt-multi-thread"] } chrono = "0.4.39" diff --git a/content/im-not-mad-im-disappointed.md b/content/im-not-mad-im-disappointed.md index 9f68e5f..4d081d3 100644 --- a/content/im-not-mad-im-disappointed.md +++ b/content/im-not-mad-im-disappointed.md @@ -2,6 +2,7 @@ title: I'm not mad, I'm disappointed description: A short rant about the state of your nix code date: 09/01/2025 +updated: 07/02/2025 tags: - nix --- diff --git a/src/data/blog.rs b/src/data/blog.rs index 4257007..04c9f38 100644 --- a/src/data/blog.rs +++ b/src/data/blog.rs @@ -4,7 +4,6 @@ use atom_syndication::{ use chrono::TimeZone; use comrak::{markdown_to_html, Options as ComrakOptions}; use lazy_static::lazy_static; -use nom::{branch::permutation, IResult}; use rust_embed::{Embed, EmbeddedFile}; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -25,6 +24,7 @@ struct Content; pub struct Post { title: String, date: String, + updated: Option, description: String, slug: String, tags: Vec, @@ -33,109 +33,54 @@ pub struct Post { id: Option, } -struct PostMeta { +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct PostMeta { title: String, date: String, + updated: Option, description: String, tags: Vec, } impl Post { + pub fn parse_meta(input: &str) -> Result> { + serde_norway::from_str(input).map_err(std::convert::Into::into) + } + + pub fn parse_content(input: &str) -> String { + let mut opts = ComrakOptions::default(); + + opts.extension.strikethrough = true; + opts.extension.table = true; + opts.extension.header_ids = Some(String::new()); + opts.extension.underline = true; + opts.extension.alerts = true; + + markdown_to_html(input, &opts) + } + pub fn parse(input: &str) -> Result> { let raw = input.split("---\n").collect::>(); let raw_metadata = raw[1]; let raw_content = raw[2]; - let meta = permutation(( - Self::parse_title, - Self::parse_date, - Self::parse_description, - Self::parse_tags, - ))(raw_metadata) - .map(|(_, (title, date, description, tags))| PostMeta { - title, - date, - description, - tags, - }); - - let meta = match meta { - Ok(meta) => meta, - Err(e) => { - eprintln!("{e:?}"); - return Err(Box::new(std::io::Error::new( - std::io::ErrorKind::Other, - e.to_string(), - ))); - } - }; - + let meta = Self::parse_meta(raw_metadata)?; let content = Self::parse_content(raw_content); let read_time_seconds = estimated_read_time::text(&content, &ERT_OPTIONS).seconds(); let read_time = read_time_seconds / 60; - let ret = Self { + Ok(Self { title: meta.title, date: meta.date, + updated: meta.updated, description: meta.description, - tags: meta.tags, slug: String::new(), + tags: meta.tags, content, read_time, id: None, - }; - - Ok(ret) - } - - fn parse_field<'a>(input: &'a str, field: &'a str) -> IResult<&'a str, String> { - let (input, _) = nom::bytes::complete::tag(field)(input)?; - let (input, _) = nom::character::complete::multispace0(input)?; - let (input, _) = nom::bytes::complete::tag(":")(input)?; - let (input, _) = nom::character::complete::multispace0(input)?; - let (input, value) = nom::character::complete::not_line_ending(input)?; - let (input, _) = nom::character::complete::newline(input)?; - Ok((input, value.to_string())) - } - - fn parse_title(input: &str) -> IResult<&str, String> { - Self::parse_field(input, "title") - } - - fn parse_date(input: &str) -> IResult<&str, String> { - Self::parse_field(input, "date") - } - - fn parse_description(input: &str) -> IResult<&str, String> { - Self::parse_field(input, "description") - } - - fn parse_tags(input: &str) -> IResult<&str, Vec> { - let (input, _) = nom::bytes::complete::tag("tags")(input)?; - let (input, _) = nom::character::complete::multispace0(input)?; - let (input, _) = nom::bytes::complete::tag(":")(input)?; - let (input, _) = nom::character::complete::multispace0(input)?; - let (input, tags) = nom::multi::many0(nom::sequence::preceded( - nom::sequence::pair( - nom::character::complete::multispace0, - nom::bytes::complete::tag("- "), - ), - nom::character::complete::not_line_ending, - ))(input)?; - let (input, _) = nom::character::complete::newline(input)?; - Ok((input, tags.iter().map(|s| (*s).to_string()).collect())) - } - - fn parse_content(input: &str) -> String { - let mut opts = ComrakOptions::default(); - opts.extension.strikethrough = true; - opts.extension.table = true; - opts.extension.header_ids = Some(String::new()); - opts.extension.underline = true; - opts.extension.alerts = true; - - markdown_to_html(input, &opts) + }) } } @@ -200,7 +145,7 @@ impl Posts { ) .updated({ let latest_post = self.0.last().unwrap(); - parse_post_date(&latest_post.date) + parse_post_date(latest_post.updated.as_ref().unwrap_or(&latest_post.date)) }) .entries( self.0 @@ -219,7 +164,7 @@ impl Posts { .build(), ) .id(&url) - .updated(parse_post_date(&post.date)) + .updated(parse_post_date(post.updated.as_ref().unwrap_or(&post.date))) .build() }) .collect::>(), @@ -316,6 +261,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "02/01/2024".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world".to_string(), tags: vec!["test".to_string(), "post".to_string()], @@ -326,6 +272,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "02/01/2024".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world".to_string(), tags: vec!["post".to_string()], @@ -346,6 +293,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "02/01/2024".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world-1".to_string(), tags: vec!["test".to_string(), "post".to_string()], @@ -356,6 +304,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "02/01/2024".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world-2".to_string(), tags: vec!["post".to_string()], @@ -376,6 +325,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "2021-08-01".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world-1".to_string(), tags: vec!["test".to_string(), "post".to_string()], @@ -386,6 +336,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "02/01/2024".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world-2".to_string(), tags: vec!["post".to_string()], @@ -406,6 +357,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "02/01/2023".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world-1".to_string(), tags: vec!["test".to_string(), "post".to_string()], @@ -416,6 +368,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "02/01/2024".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world-2".to_string(), tags: vec!["post".to_string()], @@ -426,6 +379,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "02/03/2024".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world-2".to_string(), tags: vec!["post".to_string()], @@ -436,6 +390,7 @@ mod tests { Post { title: "Hello, World!".to_string(), date: "01/03/2024".to_string(), + updated: None, description: "This is a test post".to_string(), slug: "hello-world-2".to_string(), tags: vec!["post".to_string()], diff --git a/templates/layouts/base.tera b/templates/layouts/base.tera index 0d2ae79..926bc30 100644 --- a/templates/layouts/base.tera +++ b/templates/layouts/base.tera @@ -34,7 +34,7 @@ - + {# #} {% block additionalhead %} {% endblock %}