Architecture

Architecture

This document provides a technical overview of mbr’s architecture, design decisions, and implementation details.

High-Level Overview

flowchart TD
    subgraph Input
        FILES[Markdown Files]
        CONFIG[.mbr/ Config]
    end

    subgraph Core
        SCANNER[Repository Scanner]
        PARSER[Markdown Parser]
        RESOLVER[Path Resolver]
        TMPL[Template Engine]
    end

    subgraph Output
        SERVER[Axum Server]
        BUILD[Static Builder]
        GUI[Native Window]
    end

    FILES --> SCANNER
    CONFIG --> TMPL
    SCANNER --> RESOLVER
    RESOLVER --> PARSER
    PARSER --> TMPL
    TMPL --> SERVER
    TMPL --> BUILD
    SERVER --> GUI

Rust Modules

ModulePurpose
main.rsEntry point, CLI mode selection
cli.rsCommand-line argument parsing (clap)
config.rsConfiguration loading (figment)
server.rsHTTP server (axum)
build.rsStatic site generator
browser.rsNative GUI window (wry/tao)
path_resolver.rsURL to file path resolution
markdown.rsMarkdown parsing (pulldown-cmark)
templates.rsTemplate rendering (tera)
repo.rsRepository scanning
vid.rsVideo shortcode handling
oembed.rsURL metadata extraction
quicklook.rsmacOS QuickLook extension
errors.rsError type definitions

Request Flow

flowchart TD
    REQ["HTTP Request<br/>/docs/guide/"] --> HANDLER[Request Handler]
    HANDLER --> RESOLVER["Path Resolver<br/>resolve_request_path()"]

    RESOLVER --> |MarkdownFile| PARSE["Parse Markdown<br/>+ Extract Frontmatter"]
    RESOLVER --> |StaticFile| SERVE[Serve File]
    RESOLVER --> |DirectoryListing| LIST[Generate Listing]
    RESOLVER --> |NotFound| E404[404 Response]

    PARSE --> RENDER[Render Template]
    LIST --> RENDER
    RENDER --> CACHE["Add Cache Headers<br/>ETag, Last-Modified"]
    CACHE --> RESP[HTTP Response]
    SERVE --> RESP

Path Resolution

The ResolvedPath enum represents resolution outcomes:

enum ResolvedPath {
    MarkdownFile(PathBuf),
    StaticFile(PathBuf),
    DirectoryListing(PathBuf),
    NotFound,
}

Resolution order:

  1. Direct file match → StaticFile
  2. Directory + index file → MarkdownFile
  3. Path with / suffix matching .md file → MarkdownFile
  4. File in static folder → StaticFile
  5. Directory without index → DirectoryListing
  6. Nothing matches → NotFound

Design Decisions

On-the-Fly Rendering

mbr renders markdown on every request rather than using caches:

Rationale:

Performance:

No Temp Files

mbr never writes to the filesystem during normal operation:

Rationale:

Exception: Static build mode writes to output directory.

Static builds use symlinks instead of copying assets:

Rationale:

Limitation: Requires Unix-like OS (macOS, Linux).

Parallel Scanning

Repository scanning uses rayon for parallelism:

// Parallel directory traversal
files.par_iter().for_each(|file| {
    // Process each file concurrently
});

Benefits:

Template Fallback Chain

Templates resolve through a layered system:

1. --template-folder flag
2. .mbr/ folder in repo
3. Compiled-in defaults

Each layer can override specific files while inheriting others.

Performance Goals

mbr prioritizes speed in these areas:

AreaGoalApproach
Server startup< 1 secondLazy initialization
Page render< 50msSIMD markdown, in-memory template caching
Site build< 1 file/msParallel rendering
Static page load< 100msMinimal JS, client caching

Optimization Techniques

Lazy Loading:

Concurrent Processing:

Efficient Data Structures:

Key Dependencies

CratePurpose
axumHTTP server framework
tokioAsync runtime
pulldown-cmarkMarkdown parsing
teraTemplate engine
figmentConfiguration management
wryWebView wrapper
taoWindow management
mudaNative menu bar
rayonParallel iteration
papayaConcurrent hash maps
proptestProperty-based testing

Error Handling

mbr uses custom error types with thiserror:

#[derive(thiserror::Error, Debug)]
pub enum MbrError {
    #[error("Configuration error: {0}")]
    Config(#[from] ConfigError),

    #[error("Build error: {0}")]
    Build(#[from] BuildError),

    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),
}

Errors propagate with context.

Testing Strategy

TypeLocationPurpose
Unit testssrc/*/testsModule behavior
Property testssrc/*/proptestsInvariant verification
Integration teststests/HTTP endpoint testing
Doc testsInlineExample correctness

Property-Based Testing

Key invariants verified with proptest:

Future Considerations

Potential Optimizations

Extensibility Points