Notes from Blog Engine Rewrite in Rust
Motivation and Problems
For the “Love of the Game”, the game being teaching myself enough Rust to have trenchant opinions on other languages. Things I’d like it to do:
- Markdown Rendering.
There’s CommonMark and GFM. I have special markup that will require me to extend these. Not sure if I’ll need both specs. - TSX for templating.
Because I argue it’s the best templating language ever. - SASS and Tailwind Rendering.
Usegrassfor the former. - Live-Reloading
For posts and all assets. - Asset Management
Thumbnails, optimized WebP generation, folder organization.
Development Log (of sorts)
Ah the famous learning curve. But you can be very productive with Rust if you know what to focus on. For baby Rustaceans like me who’re prototyping, the big things are:
- Not fighting the famed Borrow Checker
- Not using lifetimes as much as possible
- Just waving away any possible errors for now
- Knowing about and using popular libraries
That’s it. Concretely,
cloneandowneverything to avoid fighting the borrow checker and dealing with explicit lifetimes.unwraporexpectto avoid handling the failure cases insideResultandOption.
I’ll add a few more:
- Use
Stringinstead of&str(avoids borrowing/owning) - Use
Vec<T>to get owned collections (avoids borrowing/owning) - Use
Arc<T>to shareTacross threads (avoids lifetimes)
So yeah, you’re side-stepping what makes Rust ‘great’ in the first place. But going back and dealing with these things is for the next iteration of your app. Super-easy to do so: grep for these things and work at them.
Other Prototyping Shortcuts
- Use
dbg!a lot. - TODO: Complete this.
Datetime
Rust’s STDLIB is as shit as Python’s with datetime manipulation (which is rather disappointing). Here’s things it can and cannot do:
| Action | Can it? |
|---|---|
| Current timestamp | Yes |
| Measure elapsed time | Yes |
| Add seconds to timestamp | Yes |
| Get year/month/day | No |
| Format as 2026-10-09 | No |
| Parse ISO 8601 dates | No |
| Time zones | No |
| Calendar arithmetic | No |
Like Python you are expected to use richer libraries: chrono or jiff (I like the latter.)
Strings
Concatenation
Just use format!(). Rust’s version of Python f-strings.
Also, .display() returns &str and .to_str() returns Option<&str>. So you used:
let pattern = format!("{}/**/*.md", content_dir.display());
Here’s some concatenation drama:
let a = String::from("foo");
let s = a + "/bar"; // ok: String + &str
let s = "foo" + "bar"; // error: &str + &str
let s = "foo".to_owned() + "bar"; // ok
Miscellaneous
HAD TO ENABLE “AUTO COMMENT BLOCKS” PLUGIN FOR FUCKING COMMENT CONTINUATIONS (and that too with Shift+Enter)
References
- Great explainer on Async Rust
- FrontMatter parser (really a wrapper)