Parse a human duration string ("10m", "90s", "1h30m") into milliseconds.
Used by the :time_budget option (--time-budget) — a wall-clock budget for the
per-mutant phase (see Mutare.Runner). The grammar is deliberately tiny: one or
more <integer><unit> segments, units h/m/s, in descending order, each
optional but at least one required. Any non-negative integer is allowed in a
segment (so "90s" and "1h90m" are fine — there is no 0–59 range check), and the
total must be positive.
A bare number with no unit ("600") is rejected — the unit would be ambiguous — as
is any other malformed input (wrong order, an unknown unit, a unit with no number).
The parser never guesses; callers get an {:error, reason} they can surface verbatim.
iex> Mutare.Duration.parse("1h30m")
{:ok, 5_400_000}
iex> Mutare.Duration.parse("90s")
{:ok, 90_000}
iex> match?({:error, _}, Mutare.Duration.parse("600"))
true
iex> match?({:error, _}, Mutare.Duration.parse("30s10m"))
true
Summary
Functions
@spec parse(term()) :: {:ok, pos_integer()} | {:error, String.t()}