Saaru - Rust India May 2023 Meetup

$ whoami

Hello, I'm Anirudh!

  • Backend and Distributed Systems Dev
  • Databases Enthusiast (I call feb 14th WALentine's day)
  • 3.99999th Year CSE @ PES
  • Lab Head, PES Innovation Lab
  • Rust, Golang
  • accidental poet

What is Saaru?

  • Saaru is a Static Site Generator -> In simple words, it takes in Markdown files, a bunch of templates, and spits out a whole website.

  • Why is it called Saaru?

    • Saaru is the Kannada word for rasam and I love rasam

Architecture

                         STATIC SITE GENERATOR INTERNALS

      ┌────────────────┐
      │ Markdown Files │--------\
      └────────────────┘        |
                                v
      ┌────────────────┐     ┌─────────────┐    ┌──────────────────┐
      │ Template Rules │---->│ Static Site │--->│ Full Built HTML  │
      └────────────────┘     │ Generator   │    │ and CSS Website  │
                             └─────────────┘    └──────────────────┘
      ┌────────────────┐        ^
      │ Additional     │--------|
      │ Metadata       │
      └────────────────┘

  • The content lives as .md files enriched with frontmatter, which is YAML, TOML or JSON that you can add at the top of a markdown file.

  • You combine these files with a template, which can literally be a string with special blocks to substitute text in, or a more specialized dialect of templating like Jinja, Nunjucks, etc

  • Saaru is built on combining a Markdown Engine, a Templating Engine, and Content Injection



                      MARKDOWN ENGINE

         ┌────────┐      ┌────────┐        ┌─────────────┐
         │.md file│----->│Markdown│------->│compiled HTML│
         └────────┘      │Engine  │        │output       │
                         └────────┘        └─────────────┘

  • Saaru is a static site generator in Rust
    • (show docs folder) Give it a folder with Markdown Content and Some Templates, Saaru will render a website (show build folder)
    • Deep Data Merge: You can have content show up in indices like tags and collections, so that you can reference them in other parts of the site
  • Switches from a one-pass traversal of the dir tree to a two-pass approach (or does it? :sus:)

    • The frontmatter
    • Controls the title, a bunch of other stuff - here's what the frontmatter looks like
  • Frontmatter is metadata you can control. Here's what this looks like -> Each .md file has this, and this can control how it gets rendered.

#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct FrontMatter {
	pub title: Option<String>,
	pub description: Option<String>,
	pub date: Option<String>,
	pub tags: Option<Vec<String>>,
	pub collections: Option<Vec<String>>,
	pub wip: Option<bool>,
	pub template: Option<String>,
	pub link: Option<String>,
	pub meta: Option<Value>,
}

Live Demo (with my website)

  • Here's a working Saaru website. See the structure, and the frontmatter.

commit walkthrough from the bottom up

  • Frontmatter struct represents a file, content, tags and all

talk about how initial R&D Happened

adding other features

  • Static folder copying for CSS, etc (src/utils.rs -> pub fn copy_recursively, shamelessly stolen from the internet)
    • Basic JSON content injection
    • Skipping non-markdown files in the parse tree
    • Yet Another Refactor!

live reload

  • Added basic live reload with notify -> loop {poll_fs, if file changes, rerender that file in-place with instance.render_individual_file(filepath)} (https://github.com/anirudhRowjee/saaru/commit/c612455d70d911897742456dd0951c8b91dbcb1c)

    • had to manually refresh browser and external web server!
    • Initially architectured it as a separate module that consumed the saaru instance
    • Re-architected when adding a live server (https://github.com/anirudhRowjee/saaru/commit/b5f96fff134ab1db656872de8e19a7acb196becb)
    • New Fancy Diagram!
    • crossbeam MPMC channels, watching for fs change, waiting to notify Saaru Instance as well as web server (for live reload) -> notify, tower, tower-http-livereload
  • 2 lightweight threads (watcher thread, message passing thread)

    • Hid these configurations behind command line flags
    • Specific actions for different types of files
    • .md -> Optimized re-render of single file only
    • .css -> separate watcher thread for static files, copy that specific file over into the build folder if there's a change

future plans

  • DAG solver -> more fine-grained re-rendering to check what templates etc need to be re-loaded
  • maybe add template livereload live while i have time

Published on: 2023-05-27
Tags: featured WIP rust tech Collections: tech