Module fmt/index

fmt/index
Stability: unstable — the four printers are frozen in practice (they are Rust's `println!` family minus the macro, every name in the tree calls them, and nothing about their signature is in question), but this module's job is to BE the surface of `std/fmt`, and three of the four things it re-exports are themselves unstable: `Debug` is one release old (D15), `FormatSpec` has no dynamic width or precision, and `StringBuilder` still carries the number renderers that retired into it from `Writer`. Each says so in its own `## Stability` section. There is no open question about `print`/`println` itself; freezing this file means freezing what it forwards. — stable modules only change additively; this one may still change.

Formatted output to stdout and stderr.

Four printers over one body: println / print write to stdout, eprintln / eprint to stderr, and each takes any T <: ToString, so a template string (`x = ${v}`) and a bare value are the same call. Output goes straight to the C FILE* with fwrite — line-buffered on a tty, block-buffered into a pipe, and NOT flushed here, so interleaving stdout with stderr in a redirected run can reorder.

This is also the front door for the formatting vocabulary: ToString and Debug (./to_string.yo), Format and the value.format(spec) protocol (./format.yo), FormatSpec (./spec.yo), and — re-exported from std/string because the dependency may only run that way — StringBuilder and Alignment.

Stability

unstable — the four printers are frozen in practice (they are Rust's println! family minus the macro, every name in the tree calls them, and nothing about their signature is in question), but this module's job is to BE the surface of std/fmt, and three of the four things it re-exports are themselves unstable: Debug is one release old (D15), FormatSpec has no dynamic width or precision, and StringBuilder still carries the number renderers that retired into it from Writer. Each says so in its own ## Stability section. There is no open question about print/println itself; freezing this file means freezing what it forwards.

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.

Methods
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

StringBuilder object
StringBuilder

Mutable buffer for building a String incrementally.

Use StringBuilder when you need to construct a string from many parts, appending bytes or strings in a loop, before converting to an immutable String with to_string().

Example

sb := StringBuilder.new();
sb.write_str("Hello");
sb.write_str(", ");
sb.write_string(`world`);
sb.write_byte(u8(33));  // '!'
result := sb.to_string();
assert(result == `Hello, world!`, "built string");

Fields

NameTypeDescription
_bufArrayList(u8)
Methods
new : (StringBuilder) fn() -> StringBuilder

Create a new, empty StringBuilder.

Returns: StringBuilder

with_capacity : (StringBuilder) fn(capacity : usize) -> StringBuilder

Create a StringBuilder pre-allocated for capacity bytes.

Parameters

NameTypeNotes
capacityusize

Returns: StringBuilder

len : (StringBuilder) fn(self : StringBuilder) -> usize

Returns the current number of bytes in the buffer.

Parameters

NameTypeNotes
selfStringBuilder

Returns: usize

is_empty : (StringBuilder) fn(self : StringBuilder) -> bool

Returns true if the buffer is empty.

Parameters

NameTypeNotes
selfStringBuilder

Returns: bool

write_str : (StringBuilder) fn(self : StringBuilder, s : str) -> unit

Append a str (raw byte slice) to the buffer.

Parameters

NameTypeNotes
selfStringBuilder
sstr

Returns: unit

write_string : (StringBuilder) fn(self : StringBuilder, s : String) -> unit

Append a String to the buffer.

Parameters

NameTypeNotes
selfStringBuilder
sString

Returns: unit

write_byte : (StringBuilder) fn(self : StringBuilder, b : u8) -> unit

Append a single byte to the buffer.

Parameters

NameTypeNotes
selfStringBuilder
bu8

Returns: unit

write_rune : (StringBuilder) fn(self : StringBuilder, r : rune) -> unit

Append a single Unicode code point, encoded as UTF-8.

Example

sb := StringBuilder.new();
sb.write_rune(rune(0x1F600));  // 😀
sb.write_rune(rune(0x41));     // 'A'

Parameters

NameTypeNotes
selfStringBuilder
rrune

Returns: unit

write_line : (StringBuilder) fn(self : StringBuilder, s : String) -> unit

Append a String followed by a newline byte (\n).

Parameters

NameTypeNotes
selfStringBuilder
sString

Returns: unit

to_string : (StringBuilder) fn(self : StringBuilder) -> String

Detach the accumulated bytes as a String, leaving the builder EMPTY and still usable.

It does not copy and it does not consume the builder: the receiver is a reference, and it starts over with a fresh buffer, so building an N-byte string costs O(N) once. The returned String is therefore independent — a later write_* on the same builder cannot mutate a string already handed to a caller.

Parameters

NameTypeNotes
selfStringBuilder

Returns: String

write_hex : (StringBuilder) fn(self : StringBuilder, n : u64) -> unit

Append an unsigned 64-bit integer in lowercase hexadecimal.

Parameters

NameTypeNotes
selfStringBuilder
nu64

Returns: unit

write_f64 : (StringBuilder) fn(self : StringBuilder, n : f64, precision : i32) -> unit

Append n with exactly precision decimal places.

Parameters

NameTypeNotes
selfStringBuilder
nf64
precisioni32

Returns: unit

write_padded : (StringBuilder) fn(self : StringBuilder, s : str, width : usize, pad : rune, align : Alignment) -> unit

Append s padded to width RUNES with pad, aligned per align. A s already at or over the width is written unpadded.

Width is a RUNE count, matching FormatSpec's {:width$} and Rust's. It used to be a BYTE count here, so write_padded("héllo", 8, ' ', .Left) emitted two spaces instead of three and the column did not line up — the two width bases in one module disagreed (issues/fixed/write-padded-counted-bytes-where-formatspec-counts-runes.md).

Parameters

NameTypeNotes
selfStringBuilder
sstr
widthusize
padrune
alignAlignment

Returns: unit

clear : (StringBuilder) fn(self : StringBuilder) -> unit

Empty the builder.

This RELEASES the buffer rather than retaining its capacity — unlike Rust's String::clear and unlike ArrayList.clear, both of which keep the allocation for reuse. A builder cleared in a loop therefore reallocates from zero on every pass; when that matters, keep a fresh builder per iteration instead (it costs the same) or hand the bytes off with to_string(), which detaches for the same price. (issues/stddoc-str-string-builder-clear-drops-capacity.md)

Parameters

NameTypeNotes
selfStringBuilder

Returns: unit

default : (StringBuilder) fn() -> StringBuilder

The default value of the type.

Returns: StringBuilder

Alignment enum
Alignment

Where the text sits inside a padded field — the argument to write_padded, and the same three cases FormatSpec parses from < / > / ^.

It lives here rather than in std/fmt because write_padded does, and std/fmt already depends on std/string; the other direction would be a cycle. std/fmt re-exports it, so importing it from std/fmt works too.

Variants

VariantFieldsDescription
Left
Right
Center

Traits / Modules

ToString trait
ToString

Methods

to_string : fn(self : Self) -> String

Parameters

NameTypeNotes
selfSelf

Returns: String

Implementors

Debug trait
Debug

Methods

debug_string : fn(self : Self) -> String

Parameters

NameTypeNotes
selfSelf

Returns: String

Functions

println function
fn(generic(T : Type), v : T, where(T <: ToString)) -> unit

Print a value that implements ToString to stdout, followed by a newline.

Type Parameters

NameTypeNotes
TTypecomptime

Parameters

NameTypeNotes
vT

Returns: unit

print function
fn(generic(T : Type), v : T, where(T <: ToString)) -> unit

Print a value that implements ToString to stdout, without a trailing newline.

Type Parameters

NameTypeNotes
TTypecomptime

Parameters

NameTypeNotes
vT

Returns: unit

eprintln function
fn(generic(T : Type), v : T, where(T <: ToString)) -> unit

Print a value that implements ToString to stderr, followed by a newline.

Type Parameters

NameTypeNotes
TTypecomptime

Parameters

NameTypeNotes
vT

Returns: unit

eprint function
fn(generic(T : Type), v : T, where(T <: ToString)) -> unit

Print a value that implements ToString to stderr, without a trailing newline.

Type Parameters

NameTypeNotes
TTypecomptime

Parameters

NameTypeNotes
vT

Returns: unit