Skip to content
CryoCryo home
Stdlibfmt

spec

import std::fmt::spec; · source

Types

FmtSpec

type struct FmtSpec {
    fill:          u32;
    align:         u8;
    alternate:     boolean;
    zero_pad:      boolean;
    width:         u64;
    has_precision: boolean;
    precision:     u64;
    radix:         u8;

    static empty() -> FmtSpec;
}

An f-string hole may carry a spec after a colon. The grammar is a subset of Rust's:

spec := [[fill]align][#][0][width][.precision][type]
align := '<' | '>' | '^'         (left, right, centre)
type  := 'x' | 'X' | 'o' | 'b'   (hex lower/upper, octal, binary)
f"{value:>8}"        // right-align in a field of 8
f"{byte:#04x}"       // 0x0f  - `#` adds the radix prefix, `0` zero-pads
f"{ratio:.3}"        // three fractional digits
f"{label:*^12}"      // centred, padded with '*'

width is a minimum field width measured in Unicode scalars. .precision truncates a Display value to that many scalars, or sets the fractional digits of a float. Alignment defaults to left for text and numbers alike — chosen for predictability over a type-dependent default — and an explicit > or ^, or the 0 flag, overrides it.

For a signed integer, a decimal spec keeps the sign, while a radix formats the two's-complement bit pattern at the value's own width with no sign.

FmtSpec is the parsed form of that grammar, and fmt_parse_spec is the parser. fmt_append_fmt calls it at runtime for every hole that has a spec, then routes the value through the width-aware writers below.

Properties

PropertyType
fillu32
alignu8
alternateboolean
zero_padboolean
widthu64
has_precisionboolean
precisionu64
radixu8

Constructors

static empty() -> FmtSpec;

BodyText

type struct BodyText {
    text:     String;
    head_len: u64;
}

What a *_body writer hands back: the rendered text and how many of its leading bytes are the "head" — the sign and any radix prefix, which zero-padding must keep leftmost.

Properties
PropertyType
textString
head_lenu64

Free Functions

function fmt_parse_spec(spec: Str) -> FmtSpec;

Parse a spec string (the text after the : in a hole) into a FmtSpec. The compiler has already validated the grammar, so this walks it without re-checking; an unexpected byte is simply ignored.

fmt_append_fmt calls it at runtime for every hole that carries a spec.

Writers

A spec is applied in two steps: a *_body function renders the value to text and reports how many leading bytes are the "head" — the sign and any radix prefix, which zero-padding must keep leftmost — and fmt_pad applies fill, alignment, and width around it. They are public so a Display impl that wants to honour a spec itself can reuse them.

function fmt_uint_body(val: u64, spec: &FmtSpec) -> BodyText;

Body for an unsigned integer: optional radix prefix + digits. head (out-param via the returned struct) is the prefix length.

function fmt_sint_body(val: i64, masked: u64, spec: &FmtSpec) -> BodyText;

Body for a signed integer. Decimal keeps the sign; a radix formats the two's-complement bit pattern masked (already narrowed to the value's own width by the caller) with no sign: -1i8 in hex is ff.

function fmt_float_body(val: f64, spec: &FmtSpec) -> BodyText;

Body for a float. With a precision, uses fixed fractional digits; without, the default shortest round-trip form. The sign is part of the text, so head_len marks a leading - for zero-fill.

function fmt_display_body<T>(value: &T, spec: &FmtSpec) -> BodyText where T: Display;

Body for any Display value that is not an integer or float: render it, then truncate to precision scalars if one is set.

function fmt_pad(out: mut &String, body: Str, head_len: u64, spec: &FmtSpec) -> void;

Pad body to the spec's field width and append it to out. head_len is the leading sign/prefix run for sign-aware zero-fill.

Constants

Field values

const RADIX_NONE:      u8  = 0;
const RADIX_HEX_LOWER: u8  = 1;
const RADIX_HEX_UPPER: u8  = 2;
const RADIX_OCT:       u8  = 3;
const RADIX_BIN:       u8  = 4;
const ALIGN_DEFAULT:   u8  = 0;
const ALIGN_LEFT:      u8  = 1;
const ALIGN_RIGHT:     u8  = 2;
const ALIGN_CENTER:    u8  = 3;
const FILL_SPACE:      u32 = 0x20;
const FILL_ZERO:       u32 = 0x30;