Module fmt/spec

fmt/spec
Stability: unstable — two shapes are still open, and both are breaking to change. The grammar is missing Rust's DYNAMIC width and precision (`{:w$}`, `{:.p$}`), as the module header says. Yo has no format macro to collect the extra arguments, so adding them means inventing a spelling (`spec.with_width(n)`? a second `pad` overload?) rather than extending the parse table. And `parse` is TOTAL: it never reports a bad spec, it ignores what it does not recognise, so `"{:.2x"` degrades silently to something a caller did not ask for. That is the right default for interpolation — a typo in a log line should not abort the program — but it also means a spec typo is invisible forever, and giving `parse` a `Result` later is breaking. Freezing waits on deciding both, not on a release count. — stable modules only change additively; this one may still change.

Format specifications — the ${value:spec} vocabulary (STD_API_AUDIT D3.10).

The grammar is Rust's, minus dynamic width/precision:

spec := [[fill]align][+][#][0][width][.precision][kind]
align := "<" | ">" | "^"
kind  := "x" | "X" | "b" | "o"

Example

{ FormatSpec } :: import "std/fmt/spec";

s := FormatSpec.parse(">8.2");
s.pad(`3.14159`, Alignment.Left);   // "    3.14"

Widths and precisions are RUNE counts, not byte counts — _apply_width, pad and pad_numeric all measure with chars().count(), so é occupies one column and a truncation can never cut a rune in half. That is the one place in the string world where the unit is deliberately not bytes: a format spec describes a COLUMN, and D4's byte basis would have made accented rows come out ragged.

Stability

unstable — two shapes are still open, and both are breaking to change.

The grammar is missing Rust's DYNAMIC width and precision ({:w$}, {:.p$}), as the module header says. Yo has no format macro to collect the extra arguments, so adding them means inventing a spelling (spec.with_width(n)? a second pad overload?) rather than extending the parse table.

And parse is TOTAL: it never reports a bad spec, it ignores what it does not recognise, so "{:.2x" degrades silently to something a caller did not ask for. That is the right default for interpolation — a typo in a log line should not abort the program — but it also means a spec typo is invisible forever, and giving parse a Result later is breaking. Freezing waits on deciding both, not on a release count.

Types

FormatSpec struct
FormatSpec

A parsed format specification. Produced by parse, never written by hand — which is why the optional parts are Option rather than sentinels.

Fields

NameTypeDescription
fillrune

Padding character. Defaults to a space.

alignOption(Alignment)

Explicit alignment, if the spec gave one.

plusbool

+ — always show a sign on numbers.

altbool

# — alternate form, i.e. the 0x / 0b / 0o radix prefix.

zerobool

0 — pad numbers with zeros BETWEEN the sign/prefix and the digits.

widthusize

Minimum width in CHARACTERS.

precisionOption(usize)

.N — decimal places for floats, or a truncation length for text.

kindrune

Radix selector: x, X, b, o, or \0 for none.

impl(FormatSpec, ...)
empty : (FormatSpec) fn() -> FormatSpec

The default spec: no width, no precision, no radix.

Returns: FormatSpec

parse : (FormatSpec) fn(s : str) -> FormatSpec

Parse a spec. TOTAL: anything unrecognised is ignored rather than rejected, so a malformed spec degrades to plain to_string() output instead of failing at runtime.

Parameters

NameTypeNotes
sstr

Returns: FormatSpec

pad : (FormatSpec) fn(self : FormatSpec, body : String, dflt : Alignment) -> String

Apply width/fill/alignment (and text truncation) to an already-rendered body. dflt is the alignment used when the spec did not give one — Left for text, Right for numbers, as in Rust.

Parameters

NameTypeNotes
selfFormatSpec
bodyString
dfltAlignment

Returns: String

pad_numeric : (FormatSpec) fn(self : FormatSpec, sign : String, prefix : String, digits : String) -> String

Number-aware padding: with 0 set and no explicit alignment, the zero fill goes BETWEEN the sign/prefix and the digits, so -0042 and 0x0000002a are reachable. Otherwise this is ordinary right-aligned padding over the whole rendering.

Parameters

NameTypeNotes
selfFormatSpec
signString
prefixString
digitsString

Returns: String