htoprs 0.3.0

A faithful Rust port of htop — the interactive process viewer
docs.rs failed to build htoprs-0.3.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: htoprs-0.4.1
██╗  ██╗████████╗ ██████╗ ██████╗ ██████╗ ███████╗
██║  ██║╚══██╔══╝██╔═══██╗██╔══██╗██╔══██╗██╔════╝
███████║   ██║   ██║   ██║██████╔╝██████╔╝███████╗
██╔══██║   ██║   ██║   ██║██╔═══╝ ██╔══██╗╚════██║
██║  ██║   ██║   ╚██████╔╝██║     ██║  ██║███████║
╚═╝  ╚═╝   ╚═╝    ╚═════╝ ╚═╝     ╚═╝  ╚═╝╚══════╝

Rust htop status MenkeTechnologies

[THE FAITHFUL RUST PORT OF HTOP]

"The htop C source is the spec — ported function-for-function, not reimagined."

htoprs is a faithful Rust port of htop, the interactive process viewer. Every function under src/ported/ ports a specific htop C function, cited by <File>.c:<line> in its doc comment. Created by MenkeTechnologies.

Read the Docs · Engineering Report · Port Report


Porting methodology

The C source is the specification. Ports are faithful — the original C is translated function-for-function, never reimplemented from scratch. This is enforced mechanically, following the same precedent as zshrs.

  • Spec: htop 3.5.1, 131 .c files — vendored in-repo as the vendor/htop submodule (pinned to the 3.5.1 tag) and mirrored at the developer checkout ~/forkedRepos/htop. docs/port_report.html is generated against vendor/htop; the snapshot/report tools take $HTOP_C_SOURCE (default ~/forkedRepos/htop) to point at either.
  • Port tree: src/ported/<file>.rs — one Rust module per C file. Each fn carries a /// Port of citation naming its <File>.c:<line> origin.
  • Extensions tree: src/extensions/<name>.rs — htoprs-original code that is not a translation of htop C and is therefore exempt from the port-purity gate. extensions::theme holds the named color-scheme system (31 built-in 6-color palettes plus custom-theme plumbing), and extensions::overlay the themed keyboard-help overlay, theme chooser, and theme editor (rendering into a ratatui::Buffer) — both ported from iftoprs. extensions::colors makes a chosen theme recolor the live htop UI in 256-color via a base16-style ANSI palette remap consulted at the single Ncurses::to_color choke point, and extensions::prefs persists the selection to ~/.config/htoprs/prefs.json. The overlay is wired into ScreenManager_run: c opens the theme chooser, C the editor, h/? the help overlay, g toggles the header, b toggles the border (b, not x — htop binds x to the file-locks screen).
  • Port-purity gate (build.rs): on every cargo build / cargo test / cargo check that touches src/ported/, every free fn name is checked against the htop C-function snapshot at tests/data/htop_c_fn_names.txt. A fn whose name has no C counterpart fails the build. Rust-original helpers are rejected; genuine architectural helpers must be justified in tests/data/fake_fn_allowlist.txt. The gate cannot be bypassed by cargo test --test X.
  • C-name snapshot: regenerate with tests/data/extract_c_fn_names.sh after pulling upstream htop (HTOP_C_SOURCE=~/forkedRepos/htop).
  • Stub scaffold (scripts/gen_port_stubs.py): lays out the full port surface — one module per C file, one todo!() stub pub fn per C function (named to satisfy the gate). Stubs are placeholders, not ports; replace each with a faithful body and a /// Port of cite. Already-ported modules are never overwritten.
  • Port report: scripts/gen_port_report.py walks the C source and the Rust port and writes docs/port_report.html with per-file and overall coverage, derived from source at run time (nothing hardcoded). A todo!() / unimplemented!() body is counted as stubbed, never ported, so scaffolding cannot inflate the coverage number.

Current state

The pure-logic layers are ported — string/math utilities, the container sort/search algorithms, the prime table, and the human-readable unit formatter (detailed below). Partial ports also cover the faithfully-portable subset of eight more files: Process.c (cmdline/comm string parsing, process state char), LineEditor.c (text-buffer editing and cursor motion), OptionItem.c (CheckItem/NumberItem accessors and editing), RichString.c (RichString_findChar), ListItem.c (ListItem_compare), Affinity.c (Affinity_add), History.c (the command-history ring), and Row.c (Row_printPercentage). Functions that need still-unported substrate (ncurses/RichString drawing, CRT colors, Panel, Object vtables, syscalls) remain honest todo!() stubs; the rest of the C source is likewise scaffolded with stubs so the full surface is laid out. Further parallel passes have filled in the pure-logic functions of more files — meter sum/mode math, FunctionBar widths, Object_isA, and Settings/Action/Scheduling/ Machine/GPUMeter helpers among them — each verified against the port gate and unit tests. Overall and per-file coverage — real ports vs stubs — lives in docs/port_report.html (derived from source at run time — nothing hardcoded).

Terminal backend & substrate

htoprs must render byte-for-byte identical to htop (enforced by the parity suite). The terminal layer is crossterm — pure-Rust, vendorable, cross-arch, no C dependency — giving full control over every glyph/color/attribute so the output matches htop while the draw code is a behavioral (not line-for-line) port. The substrate the UI renders through is ported: Object.c (htop's vtable OOP → a Rust Object trait with a class-chain Object_isA), RichString.c (the full styled-character buffer), and CRT.c's color model — the ColorElements enum and every CRT_colorSchemes entry transcribed verbatim so colors match htop exactly. The terminal-control fns (CRT_init/readKey, Panel/ScreenManager draw) and the platform data-collection layer (Platform_*, process scan) are the next phases.

XUtils.c — string / math utilities:

C function notes
String_cat concatenation
String_trim trims leading/trailing space, tab, newline (only those three)
String_split splits on a separator; interior empties kept, trailing empty dropped
String_splitFirst splits on first separator only
String_contains_i case-insensitive substring; |-multi-needle mode
compareRealNumbers NaN-aware ordering (NaN sorts first)
sumPositiveValues sum of strictly-positive values, NaN skipped
countDigits digit count in a given base, with overflow guard
countTrailingZeros mod-37 lowest-set-bit table

Vector.c — container sort / search core, ported as generics over a slice with a C-int-returning comparator (the Object** pointer array becomes a slice; signed isize indices preserve the C's below-left arithmetic):

C function notes
swap exchange two slots
partition Lomuto partition, pivot moved to right
quickSort recursive quicksort, pivot left + (right - left) / 2
insertionSort in-place insertion sort over [left, right]
Vector_indexOf linear search, C -1 sentinel preserved

Hashtable.c — prime-table math:

C function notes
nextPrime smallest OEIS prime >= n; aborts (panics) if none fits

Meter.c — value formatting:

C function notes
Meter_humanUnit kibibytes → human-readable string (KQ, inf cap)

The C allocation wrappers, null-terminated-string helpers, varargs formatters, and String_freeArray (XUtils.c); the Object** dynamic-array memory machinery — Vector_new / _insert / _add / _resizeIfNecessary and the rest (Vector.c); and the open-addressing bucket table — Hashtable_new / _put / _get / _foreach and the rest (Hashtable.c) — have no faithful safe-Rust analog (Rust's Vec / HashMap own allocation, bounds, probing, and lifetimes) and are intentionally not ported. combSort is commented-out dead code in Vector.c and is not ported.

Build & test

cargo build          # runs the port-purity gate
cargo test           # ports have hand-crafted unit tests pinning C edge behavior
cargo test --test parity   # diff htoprs output vs the reference htop 3.5.x
python3 scripts/gen_port_report.py   # regenerate docs/port_report.html

The parity suite (tests/parity/) runs the same inputs through the reference htop (the C original htoprs is ported from) and htoprs, then compares output byte-for-byte, modulo the deliberate rebrand (htoprshtop, version banner). It skips gracefully when no matching htop 3.5.x is installed, so CI stays green; a dev box with htop runs the real comparison. Point it at a specific reference with HTOP_REF=/path/to/htop. See docs/PARITY.md.