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.
██╗ ██╗████████╗ ██████╗ ██████╗ ██████╗ ███████╗
██║ ██║╚══██╔══╝██╔═══██╗██╔══██╗██╔══██╗██╔════╝
███████║ ██║ ██║ ██║██████╔╝██████╔╝███████╗
██╔══██║ ██║ ██║ ██║██╔═══╝ ██╔══██╗╚════██║
██║ ██║ ██║ ╚██████╔╝██║ ██║ ██║███████║
╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝
[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
.cfiles — vendored in-repo as thevendor/htopsubmodule (pinned to the 3.5.1 tag) and mirrored at the developer checkout~/forkedRepos/htop.docs/port_report.htmlis generated againstvendor/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. Eachfncarries a/// Port ofcitation 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::themeholds the named color-scheme system (31 built-in 6-color palettes plus custom-theme plumbing), andextensions::overlaythe themed keyboard-help overlay, theme chooser, and theme editor (rendering into aratatui::Buffer) — both ported from iftoprs.extensions::colorsmakes a chosen theme recolor the live htop UI in 256-color via a base16-style ANSI palette remap consulted at the singleNcurses::to_colorchoke point, andextensions::prefspersists the selection to~/.config/htoprs/prefs.json. The overlay is wired intoScreenManager_run:copens the theme chooser,Cthe editor,h/?the help overlay,gtoggles the header,btoggles the border (b, notx— htop bindsxto the file-locks screen). - Port-purity gate (
build.rs): on everycargo build/cargo test/cargo checkthat touchessrc/ported/, every freefnname is checked against the htop C-function snapshot attests/data/htop_c_fn_names.txt. Afnwhose name has no C counterpart fails the build. Rust-original helpers are rejected; genuine architectural helpers must be justified intests/data/fake_fn_allowlist.txt. The gate cannot be bypassed bycargo test --test X. - C-name snapshot: regenerate with
tests/data/extract_c_fn_names.shafter 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, onetodo!()stubpub fnper C function (named to satisfy the gate). Stubs are placeholders, not ports; replace each with a faithful body and a/// Port ofcite. Already-ported modules are never overwritten. - Port report:
scripts/gen_port_report.pywalks the C source and the Rust port and writesdocs/port_report.htmlwith per-file and overall coverage, derived from source at run time (nothing hardcoded). Atodo!()/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 (K…Q, 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
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
(htoprs→htop, 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.