35 releases (6 stable)
| new 1.2.0 | Apr 16, 2026 |
|---|---|
| 0.28.0 | Apr 3, 2026 |
| 0.27.1 | Mar 28, 2026 |
#2149 in Development tools
Used in 2 crates
(via padz)
615KB
14K
SLoC
Padz Architecture: CLI / Logic Separation
Padz is a UI-agnostic note-taking library. This is not a CLI application that happens to have some library code—it's a library that happens to have a CLI client.
Workspace Structure
Padz is organized as a Cargo workspace with two crates:
crates/padz/— This core library (UI-agnostic business logic)crates/padz-cli/— The CLI tool (depends on this library)
The Problem
Shell programs tend to conflate interface and logic. Before you know it, logic is outputting strings all over the place and calculations are converting strings to integers. This makes the program unwieldy and hard to test.
The Solution: Strict Layering
┌─────────────────────────────────────────────────────────────┐
│ CLI Layer (crates/padz-cli/) │
│ - Parses arguments, formats output, handles terminal I/O │
│ - The ONLY place that knows about stdout/stderr/exit codes │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ API Layer (api.rs) │
│ - Thin facade over commands │
│ - Normalizes inputs (indexes → UUIDs) │
│ - Returns structured Result<CmdResult> │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Command Layer (commands/*.rs) │
│ - Pure business logic │
│ - Operates on Rust types, returns Rust types │
│ - No I/O assumptions whatsoever │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Storage Layer (store/) │
│ - Abstract DataStore trait │
│ - FileStore (production), InMemoryStore (testing) │
└─────────────────────────────────────────────────────────────┘
Key Principle: No I/O Assumptions in Core
From api.rs inward, code:
- Takes regular Rust function arguments
- Returns regular Rust types (
Result<CmdResult>) - Never writes to stdout/stderr
- Never calls
std::process::exit - Never assumes a terminal environment
This means the same core could serve a REST API, a browser app, or any other UI.
The Index System
To remain ergonomic, padz uses a dual ID system mapping user-friendly display indexes
(1, p1, d1) to stable UUIDs at the data store level.
See index module for details.
Data Flow Example: padz delete 1
- CLI:
clapparses1.handle_deletereceivesvec!["1"]. - API:
parse_selectorsmaps"1"→PadSelector::Index(Regular(1)). - Command: Resolves to UUID, checks protection, marks as deleted.
- Return:
CmdResultwith message "Deleted 1 pad". - CLI: Renders the message to terminal.
Testing Strategy
| Layer | Test Type | What to Test |
|---|---|---|
| CLI | Integration | Arg parsing, output formatting |
| API | Unit | Dispatch correctness, input normalization |
| Commands | Unit | Business logic, state transitions |
| Store | Unit | Read/write operations, sync behavior |
Development Workflow
When implementing features, work inside-out:
- Logic: Implement and fully test in
commands/<cmd>.rs - API: Add facade method in
api.rs, test dispatch - CLI: Add handler in CLI crate's
commands.rs, test arg parsing and output
Module Overview
- [
api]: The API facade—entry point for all operations. Also handles selector parsing. commands: Business logic for each commandstore: Storage abstraction and implementations. See module for hybrid store architecture.model: Core data types and content normalizationindex: Display indexing system (p1, 1, d1 notation)init: Scope detection and context initializationconfig: Configuration managementeditor: External editor integrationclipboard: Cross-platform clipboard supporterror: Error types
padz (library)
Core library for padz - a fast, project-aware scratch pad.
This crate provides the UI-agnostic business logic for padz. It includes:
- API Layer (
api.rs): Thin facade over commands with input normalization - Command Layer (
commands/): Pure business logic for all operations - Store Layer (
store/): Storage abstraction with FileStore and InMemoryStore implementations - Model (
model.rs): Core data types (Pad, Metadata, Scope)
Architecture
Everything in this crate is UI-agnostic:
- Functions take normal Rust arguments and return normal Rust types
- No stdout/stderr writes
- No
std::process::exitcalls - No terminal assumptions
This enables the same core to serve CLI, web API, or any other UI.
Usage
See the main padz repository for full documentation.
For the CLI tool, install padz-cli instead:
cargo install padz-cli
Dependencies
~9–15MB
~339K SLoC