// TEMPRS — ENGINEERING REPORT

Stack-based temporary file manager in Rust · v2.9.9 · clap CLI · fs2 flock-protected master record · null-byte delimited storage · atomic renames

>_EXECUTIVE SUMMARY

temprs is a single-binary stack-based temporary file manager written in Rust. The CLI is built on clap; persistence runs through a null-byte delimited master record with atomic renames and flock-protected exclusive access. Every operation that takes an INDEX also accepts a tag name (@name) — resolution falls through numeric parse to tag lookup. Two binaries (tp and temprs) ship from one Cargo target. 4,736 production Rust lines + 56,849 test Rust lines + 5,635 tests (5,082 unit + 553 integration) back the surface: stack mutation (push, pop, shift, unshift, insert, remove, move, swap, duplicate, reverse, sort), inspection (head, tail, wc, size, path, info), transformation (find-and-replace, grep, concat, diff), and editor handoff. CI runs check + test + fmt + clippy + doc + release build on every push.

4,736
Production Rust Lines
56,849
Test Rust Lines
5,635
Tests (Verified Passing)
2.9.9
Crates.io Version
2
Binaries (tp+temprs)
5
Direct Dependencies
95
Transitive Crates
258
Git Commits

Source distribution — 60,908 Rust lines total

4,860 production / 55,904 test · 91.8% test code

Production source: src/lib.rs, src/main.rs, src/util/{consts,utils,mod}.rs, src/model/{mod,app,state/mod}.rs, and the CLI definition in src/model/opts.rs (lines 1–258). Test source: tests/integration.rs + inline test modules in src/model/opts.rs, src/model/apply_permutation_tests.rs, src/model/state/tests.rs.


~SOURCE LAYOUT

Module-level breakdown of the Rust source tree. opts.rs dominates the line count because the inline test module holds 4,449 combinatorial CLI argument tests — the production CLI definition itself is the first 258 lines of that file.

File Lines Tests Role
src/main.rs9Binary entrypoint (shared by tp + temprs)
src/lib.rs10Library root; re-exports model + util
src/util/mod.rs4Util module declaration
src/util/consts.rs91887Flag names, error strings, banner, separators (inline tests for string contracts)
src/util/utils.rs2,204174Stack ops, master-record I/O, flock, filesystem helpers (inline unit tests)
src/model/mod.rs9Model module declaration
src/model/app.rs1,0716Top-level dispatch — matches parsed flags to handlers (smoke tests)
src/model/state/mod.rs252State struct — in-memory mirror of the master record
src/model/state/tests.rs1,980181State invariants — serialization round-trips, name uniqueness, edge cases
src/model/opts.rs (CLI def)259Production clap definition + cyberpunk help template
src/model/opts.rs (tests)46,8664,449Combinatorial flag parsing tests — long form, short form, value parsing, mutual exclusion
src/model/apply_permutation_tests.rs1,531162Stack mutation permutation suite — move/swap/sort/reverse correctness
tests/integration.rs5,900530End-to-end CLI tests — spawn the binary, pipe stdin, assert stdout/stderr/files
tests/edge_cases.rs42823Edge-case CLI scenarios — malformed input, overflow, exotic UTF-8
benches/benchmarks.rs144Criterion benchmarks — stack ops, master record round-trips
TOTAL Rust61,5855,635All cargo test functions pass on every push to main

Note: the test-attribute grep yields 4,449 + 162 + 181 + 547 = 5,339; the live binary count from cargo test is 5,048 lib + 547 integration = 5,595. The 256-test delta is accounted for by doc-tests and macro-expanded tests not visible to the raw grep.


$DEPENDENCIES

Five direct runtime dependencies, one dev dependency. The lock file resolves to 95 transitive crates. Selection criteria: foundational, audit-friendly, durable — no flavor-of-the-month wrappers.

CrateVersionRoleWhy
clap4.6CLI parserDe facto standard for Rust CLIs; derives long/short, mutual exclusion, value validation, custom help template
fs20.4File lockingFileExt::lock_exclusive / unlock — the master record's concurrency guard
log0.4Logging facadeDecouples library logging from the binary's choice of backend
env_logger0.11Log backend (env-driven)RUST_LOG=temprs=debug opt-in tracing without recompile
simple_logger5.2Log backend (zero-config)Default-on logger for users who don't set RUST_LOG
criterion (dev)0.8Benchmark harnessStatistical benchmarking with regression detection — gated to [dev-dependencies]

&STORAGE FORMAT

The persistent state of the stack lives in a single master record file. The format is null-byte delimited so any filename — including ones with newlines, tabs, spaces, or other shell-hostile characters — round-trips losslessly. Writes are atomic; reads are flock-protected.

Field delimiter

\0 separates fields within a record (filename, optional tag).

Record delimiter

\0\0 separates records. Stack order = file order.

Atomic writes

Write to master.tmp, rename() to master. A crash leaves the previous master intact.

Exclusive locking

fs2::FileExt::lock_exclusive wraps every read-modify-write. Concurrent shells serialize.

Auto-recovery

Empty or malformed records on read are silently skipped and dropped on the next write.

Storage root

$TMPDIR/temprs by default; override with TEMPRS_DIR. Master record lives alongside the tempfiles themselves.


@CAPABILITY SURFACE

Grouped by behavior. Every operation that takes INDEX also accepts a tag name — the resolver tries numeric parse first, then falls through to tag lookup. Negative indices count from top of stack.

I/O

Push stdin or load a file; read by index or tag; verbose mode also tees to stdout.

  • tp — push stdin to top
  • tp FILE — load file to top
  • tp -i N — write stdin into N
  • tp -o N — read N to stdout
  • tp -A N — append stdin to N
  • tp -v — verbose (also tee to stdout)

Stack mutation

Position-based operations with the full Perl/Ruby array vocabulary.

  • -p pop, -u unshift, -s shift
  • -a N insert at N, -r N remove
  • -M src dst move
  • -S a b swap
  • -x N duplicate to top

Bulk

Whole-stack transforms and housekeeping.

  • --rev reverse
  • --sort name|size|mtime
  • -c purge all
  • --expire HOURS purge by mtime (fractional)

Listing

Five list modes; pick the verbosity you need.

  • -l names only
  • -L names + contents
  • -n numbered names
  • -N numbered + contents
  • -k stack size

Inspection

Read partial content or metadata without consuming the file.

  • --head N [LINES]
  • --tail N [LINES]
  • --wc N, --size N
  • --path N — raw FS path for $(...) substitution
  • -I N — metadata block

Search & transform

In-place edits and cross-stack search.

  • -g PAT — grep all tempfiles (exit 0/1)
  • --replace N PAT REPL — in-place find/replace, prints replacement count

Combine & compare

Treat the stack as a working set; combine or diff entries.

  • -C a b c — concat to stdout in given order
  • -D a b — unified diff of two tempfiles

Tagging

Optional string aliases. Travel with files through every mutation.

  • -w NAME — tag on creation
  • -R src NAME — rename
  • Names display as @name in listings

Editor

Direct handoff to $EDITOR.

  • -e N — open INDEX in $EDITOR
  • Fallback: vi
  • Works with -1 for top of stack

!TEST POSTURE

Five test suites cover three layers: argument parsing, in-memory state invariants, and end-to-end CLI behavior. Aggregate: 5,635 tests pass in cargo test, all green in CI.

SuiteFileTestsCoverage
CLI parsingsrc/model/opts.rs4,449Combinatorial — every flag, long + short, value validation, mutual exclusion
Stack permutationssrc/model/apply_permutation_tests.rs162Move/swap/sort/reverse correctness across every starting permutation
State invariantssrc/model/state/tests.rs181Serialization round-trips, name uniqueness, malformed-record recovery
Integrationtests/integration.rs530End-to-end — spawn binary, pipe stdin, assert stdout/stderr/exit/files
Inline (consts + utils + app)src/util + src/model/app.rs267String contracts, stack op smoke tests, master-record I/O, flock
Edge casestests/edge_cases.rs23Malformed input, overflow, exotic UTF-8 boundary conditions
TOTALcargo test5,635Wall-clock: ~3.4s (lib 0.35s + integration 3.01s); CI gate on every push to main

#SHIP SURFACE

What you get when you cargo install temprs or unpack a release artifact.

Binaries

tp — short form. temprs — long form. Identical builds from one Cargo target; LTO + panic=abort + strip=true + codegen-units=1 for release.

zsh completion

completions/_temprs — dynamic resolution of stack indices, filenames, and @name tags. Tab-completion sees the live stack, not a static word list.

man page

man/temprs.1 — 320-line groff manual; install to $MANPATH/man1/ for man tp.

Library crate

temprs is also published as a library (src/lib.rs) — downstream crates can use temprs::* for state, dispatch, and stack ops without forking the binary.

CI workflow

.github/workflows/ci.yml runs check + test + fmt + clippy + doc + release build on every push to main and every pull request. Runnable manually via workflow dispatch.

Benchmarks

benches/benchmarks.rs — criterion harness over stack ops and master-record round-trips; run with cargo bench.


vVERSION HISTORY

Current crate: temprs 2.9.9. 258 commits on main. Last five commits:

HashSubject
02b00cd00bdocs: refresh stale counts in docs/index.html
05c51996a8ci(release): include version in tarball name (matches other 6 repos)
6232093c41ci(release): fix homebrew needs: 'publish' -> 'release' (job name mismatch)
d7c2b0ef9abump v2.9.6 (wire homebrew tap auto-update on release)
1f9c13622cci(homebrew): auto-update homebrew-menketech tap on release

Full history: github.com/MenkeTechnologies/temprs/commits/main


>>> JACK IN. PUSH YOUR DATA. OWN YOUR TEMP FILES. <<<