# Research: Rust Ecosystem & Dependencies ## SQLite Access: rusqlite **Winner: [rusqlite](https://docs.rs/rusqlite/0.38) v0.38** | Feature | rusqlite | sqlx | |---------|----------|------| | Async | No (sync) | Yes | | SQLite-only | Yes | No (multi-DB) | | Bundled SQLite | Yes (feature flag) | No | | Read-only support | Yes (`SQLITE_OPEN_READ_ONLY`) | Yes | Why rusqlite: - Synchronous is fine for a CLI reading a local file - `Connection::open_with_flags(path, OpenFlags::SQLITE_OPEN_READ_ONLY)` ensures safety - `features = ["bundled"]` includes SQLite 3.49.2 — no system dependency - Simpler dependency tree than sqlx - WAL-safe: reading an Atuin DB in WAL mode from a separate process is safe ```rust use rusqlite::{Connection, OpenFlags}; let db = Connection::open_with_flags( "~/.local/share/atuin/history.db", OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX, )?; ``` ## Shell Command Parsing ### Level 1: Word splitting — shell-words [shell-words](https://docs.rs/shell-words) v1 — POSIX shell word splitting. ```rust shell_words::split("git commit -m \"fix typo\"") // → ["git", "commit", "-m", "fix typo"] ``` Simple, correct, well-maintained. Exactly what we need for command abstraction. ### Level 2: Full AST parsing (optional) | Crate | Version | Description | Maturity | |-------|---------|-------------|----------| | [brush-parser](https://docs.rs/brush-parser) | 0.3.0 | Full POSIX/bash tokenizer + parser with AST | Active, part of brush-shell | | [conch-parser](https://github.com/ipetkov/conch-parser) | 0.1.1 | Shell parser with AST builder | Stale | | [mystsh](https://crates.io/crates/mystsh) | Early | POSIX/bash parser | Newer, active | ### Level 3: Variable expansion [shellexpand](https://docs.rs/shellexpand) v3.1.1 — tilde and `$VAR` expansion. 10M+ downloads. ## TUI: ratatui **Winner: [ratatui](https://github.com/ratatui/ratatui) v0.30** | Library | Stars | Status | |---------|-------|--------| | **ratatui** | 18.6k | Active, community standard | | cursive | ~3.8k | Maintained, less active | | tui-rs | ~10k | **Unmaintained** (ratatui is the fork) | Why ratatui: - Immediate-mode rendering (you own the render loop) - Widgets: Block, Paragraph, List, Table, Chart, BarChart, Tabs, etc. - Backends: crossterm (default), termion, termwiz - 100+ third-party widgets via [awesome-ratatui](https://github.com/ratatui/awesome-ratatui) - 60+ FPS with complex layouts - Since 0.30.0: modular architecture (ratatui-core, ratatui-widgets, ratatui-crossterm) Relevant widgets for workflow dashboard: - `Table` — displaying discovered patterns - `List` — navigating workflows - `BarChart` / `Sparkline` — frequency visualization - `Tabs` — switching views ## CLI Framework: clap [clap](https://docs.rs/clap/4) v4 with derive feature — standard, ergonomic. ## Sequential Pattern Mining **No mature Rust crate exists.** Zero repos in Rust on the [sequential-pattern-mining GitHub topic](https://github.com/topics/sequential-pattern-mining). Recommended: Implement PrefixSpan directly, porting from [PrefixSpan-py](https://github.com/chuanconggao/PrefixSpan-py). ~300-500 lines of Rust. ## Justfile Generation No Rust crate for generating Justfiles. Format is simple enough for string formatting. Key syntax rules: - Recipe bodies use spaces (with `set indent`) or tabs - Recipe names: lowercase, hyphens allowed - Variables: `name := "value"`, interpolated with `{{name}}` - Dependencies: `test: build lint` - Parameters: `deploy target="default":` - Shebang recipes: first line `#!` - `@` prefix suppresses echo - Validate with `just --fmt --check --unstable -f ` ## Recommended Cargo.toml ```toml [workspace.dependencies] rusqlite = { version = "0.38", features = ["bundled"] } shell-words = "1" ratatui = "0.30" crossterm = "0.28" chrono = { version = "0.4", features = ["serde"] } clap = { version = "4", features = ["derive"] } serde = { version = "1", features = ["derive"] } serde_json = "1" serde_yaml = "0.9" anyhow = "1" dirs = "6" ```