Skip to content

refactor(hm-exec): Replace raw-string-literal job-state match with a typed classifier#124

Merged
markovejnovic merged 3 commits into
mainfrom
cq/hm-exec-replace-raw-string-literal-job-state-mat-6
Jun 10, 2026
Merged

refactor(hm-exec): Replace raw-string-literal job-state match with a typed classifier#124
markovejnovic merged 3 commits into
mainfrom
cq/hm-exec-replace-raw-string-literal-job-state-mat-6

Conversation

@markovejnovic

Copy link
Copy Markdown
Contributor

The smell

The cloud watch loop decides whether a job's logs exist by round-tripping the
typed job state through to_string() and matching the result against a
hand-written set of string literals (crates/hm-exec/src/cloud/watch.rs:113):

let state = job.state.to_string();
let logs_available = matches!(
    state.as_str(),
    "running" | "passed" | "failed" | "timed_out"
        | "canceling" | "canceled" | "timing_out"
);

This is stringly-typed flag matching. A typo in any literal compiles fine and
silently drops a job's logs, and there is no exhaustiveness check: when the
cloud adds a new JobState, this matches! keeps compiling and silently treats
the new state as "no logs".

The change

harmont_cloud already exposes job.state as a typed, exhaustive
JobState enum (it only Displays into those strings). This PR matches on the
enum variants directly via a single named, documented predicate
job_logs_available(state: JobState) -> bool, placed alongside the file's other
helpers and unit-tested. The string round-trip (to_string()/as_str()) is
removed at this call site. Behavior is preserved exactly: the true set is
Running | Passed | Failed | TimedOut | Canceling | Canceled | TimingOut, and
Pending | Scheduled | Assigned | Skipped are false (matching the original
literal set — skipped was deliberately excluded before and remains so).

Because the predicate matches every JobState variant explicitly (no
wildcard arm), adding a new cloud state becomes a compiler-visible change rather
than a silent miss.

Type-safety pattern

This applies the ValueEnum / typed-classifier doctrine seen in tools like
ripgrep and fd: push known finite string sets behind a typed enum match so
typos can't compile and missing cases are caught by exhaustiveness checking,
instead of duplicating literal sets at each call site.

Testing note

Only cargo check -p hm-exec was run locally (per task scope; the full
workspace/TS build was not run). Note: the local sandbox has a pre-existing,
unrelated compile error in crates/hm-exec/src/local/backend.rs
(ImageRegistry::open now expects NonZero<u64>, a hm-vm dependency skew)
that reproduces on the base branch and is independent of this change — the
compiler reached and resolved watch.rs with no diagnostics. Full CI runs on
this PR. Draft = needs review.

@markovejnovic markovejnovic marked this pull request as ready for review June 10, 2026 20:12
…w-string-literal-job-state-mat-6

# Conflicts:
#	crates/hm-exec/src/cloud/watch.rs
@markovejnovic markovejnovic merged commit 1b08a61 into main Jun 10, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant