FormatSpec structv0.1.0
pub struct FormatSpec {
// private fields
}
Copy, and cheap to pass: a spec is read, never held. Its representation is private, so a value applying a spec reads it and cannot alter what the placeholder asked for.
Associated functions
Plain
pub func Plain() -> FormatSpec
What a bare {} asks for: nothing at all.
Cannot fail. Runs in constant time and allocates nothing.
Returns: a spec with no width, no precision, default alignment and base ten
Methods
Fill
pub func Fill(self: &FormatSpec) -> char8
The byte that pads a rendering narrower than the width. Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: the fill byte, a space unless the placeholder named one
Alignment
pub func Alignment(self: &FormatSpec) -> FormatAlign
Where the padding goes.
Default means the value chooses, which is why it is a case rather than being resolved here: numbers pad on
the left and text on the right, and only the value knows which it is.
Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: the requested alignment, or Default when the placeholder named none
ShowsSign
pub func ShowsSign(self: &FormatSpec) -> bool
Whether a non-negative number should carry a +.
Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: true when the placeholder wrote +
IsAlternate
pub func IsAlternate(self: &FormatSpec) -> bool
Whether a based integer should carry its 0b, 0o or 0x prefix.
Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: true when the placeholder wrote #
ZeroPads
pub func ZeroPads(self: &FormatSpec) -> bool
Whether a number pads with zeros inside itself rather than with fill outside itself. Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: true when the placeholder wrote a leading 0
Width
pub func Width(self: &FormatSpec) -> uint
The fewest Unicode scalar values the rendering should occupy. Counted in scalars rather than bytes, so an accented name pads the same as an unaccented one. Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: the requested width, or zero when the placeholder asked for none
Precision
pub func Precision(self: &FormatSpec) -> uint
How many characters of text to keep, or how many digits a float carries.
Meaningful only when HasPrecision reports true: zero is a precision a caller can mean, so the value alone
cannot say whether one was asked for.
Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: the requested precision, meaningful only alongside HasPrecision
HasPrecision
pub func HasPrecision(self: &FormatSpec) -> bool
Whether the placeholder named a precision at all. Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: true when a precision was written, including .0
Base
pub func Base(self: &FormatSpec) -> FormatBase
The base an integer should render in. Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: the requested base, or Decimal when the placeholder named none
Style
pub func Style(self: &FormatSpec) -> char8[..]
The style the specification named, or an empty slice when it named none.
A value compares this against the styles it understands and reports UnsupportedRequest for anything else.
The four single-letter integer bases are also reflected in Base, so an integer has no reason to read this.
The result borrows the specification text this was parsed from and must not outlive it.
Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: the style bytes, empty when no style was written
HasStyle
pub func HasStyle(self: &FormatSpec) -> bool
Whether the specification named a style at all. Borrows the spec. Cannot fail; runs in constant time and allocates nothing.
Returns: true when a style was written
StyleIs
pub func StyleIs(self: &FormatSpec, name: char8[..]) -> bool
Whether the specification named exactly the style name.
The comparison a value makes to decide whether a style is one of its own, written once so each renderer does
not repeat a byte loop.
Borrows the spec. Cannot fail; runs in time proportional to name, and allocates nothing.
| Name | Type | Description |
|---|---|---|
name | char8[..] | the style to compare against |
Returns: true when the specification named exactly that style
Related
PaddingAround
pub func PaddingAround(
spec: FormatSpec,
occupied: uint,
numeric: bool,
before: *var uint,
after: *var uint
)
How many fill characters go on each side of a rendering that occupies occupied scalars.
Split out from WriteAligned because a numeric writer needs the two counts before it starts, so that a sign, a
base prefix and the digits can go out in order without the rendered text existing anywhere as one run.
numeric picks the default alignment: numbers sit to the right and text to the left, which is what makes a
column of numbers line up its units and a column of names line up its first letters.
Cannot fail. Runs in constant time and allocates nothing.
Parameters
| Name | Type | Description |
|---|---|---|
spec | FormatSpec | what the placeholder asked for |
occupied | uint | how many Unicode scalar values the rendering occupies |
numeric | bool | true when the value aligns like a number by default |
before | *var uint | receives the count of fill characters that precede the rendering |
after | *var uint | receives the count that follow it |
WriteFill
pub func WriteFill(
writer: &var TextWriter,
spec: FormatSpec,
count: uint
) -> ! FormatError
Writes count copies of the spec's fill byte.
Reports whatever the writer reported, stopping at the first refusal rather than continuing to a destination
that has already said no.
Parameters
| Name | Type | Description |
|---|---|---|
writer | &var TextWriter | the destination |
spec | FormatSpec | the specification whose fill byte is written |
count | uint | how many copies to write |
Returns: success when every copy was accepted
WriteAligned
pub func WriteAligned(
writer: &var TextWriter,
spec: FormatSpec,
rendered: char8[..],
numeric: bool
) -> ! FormatError
Writes rendered into writer under spec's width, fill and alignment.
Width is measured in Unicode scalar values rather than bytes, so a name with an accent pads the same as one
without. A rendering already at or past the requested width is written through unpadded.
Reports whatever the writer reported. A failure part-way leaves whatever the destination had already accepted;
what that means is the destination's own documented guarantee.
Parameters
| Name | Type | Description |
|---|---|---|
writer | &var TextWriter | the destination |
spec | FormatSpec | what the placeholder asked for |
rendered | char8[..] | the already-rendered text, which must be well-formed UTF-8 |
numeric | bool | true when the value aligns like a number by default |
Returns: success when the padded rendering was accepted in full
WriteDisplayAligned
pub func WriteDisplayAligned(
writer: &var TextWriter,
value: &Display,
spec: FormatSpec
) -> ! FormatError
Writes value's text under spec, applying the spec's width, fill and alignment around the text the value writes
itself.
For a value whose WriteDisplay writes its text in pieces, which WriteAligned cannot pad: such a value calls
this first when spec has a width. The value writes into 256 bytes of local room under the spec with no width,
which is what keeps its own call from coming back here, and the room is then padded into writer. A rendering too
long for the room is written through unpadded, since a width that short would add no padding anyway.
Reports whatever the value or the writer reported.
Parameters
| Name | Type | Description |
|---|---|---|
writer | &var TextWriter | the destination |
value | &Display | the value to render |
spec | FormatSpec | what the placeholder asked for |
Returns: success when the padded rendering was accepted in full
FormatAlign
pub enum FormatAlign: int32 {
Default = 0,
Left = 1,
Center = 2,
Right = 3
}
Where the padding goes when the rendering is narrower than the width. Copy, carrying no payload.
Cases
| Name | Value | Description |
|---|---|---|
Default | 0 | The type's own default: numbers to the right, text to the left. |
Left | 1 | The value at the start, fill after it. |
Center | 2 | The value in the middle, fill on both sides, the odd column on the right. |
Right | 3 | The value at the end, fill before it. |
FormatBase
pub enum FormatBase: int32 {
Decimal = 0,
Binary = 1,
Octal = 2,
LowerHex = 3,
UpperHex = 4
}
The base an integer renders in.
Copy, carrying no payload. A negative signed integer renders in every base as a minus sign followed by the
digits of its magnitude, not as its two's-complement bits: {:b} of -5 is -101 and {:#x} of -255 is
-0xff. That keeps the text of a value independent of the width of the type it happens to be stored in.
Cases
| Name | Value | Description |
|---|---|---|
Decimal | 0 | Base ten, the default. |
Binary | 1 | Base two, b, prefixed 0b under #. |
Octal | 2 | Base eight, o, prefixed 0o under #. |
LowerHex | 3 | Base sixteen with lower-case digits, x, prefixed 0x under #. |
UpperHex | 4 | Base sixteen with upper-case digits, X, prefixed 0x under #. |
ParseFormatSpec
pub func ParseFormatSpec(text: char8[..]) -> FormatSpec ! FormatError
Parses the text between {: and }.
The grammar is [[fill]align][+][#][0][width][.precision][style], every piece optional, so the empty
specification is well-formed and asks for nothing. A style is an identifier: an ASCII letter followed by
letters, digits, _ or -. That covers the single-letter integer bases b, o, x and X, which also set
Base so an integer need not inspect the style text, the float styles e and E for scientific notation, and
the domain styles such as iso8601 and hyphenated that a value interprets for itself.
Syntax is recognized here once; whether a style or flag applies is the value's question, since only the value
knows whether a precision means digits, characters or nothing at all. A specification this accepts may still be
refused with UnsupportedRequest by the value it is handed to.
The returned specification's style borrows text. It must not outlive the specification text it was parsed
from, and nothing here tracks that.
Reports InvalidSpecification carrying the zero-based byte offset into text where parsing stopped: an
unprintable or brace fill, a . with no digits after it, a width or precision whose arithmetic will not fit a
uint, or any byte that can begin none of the remaining pieces. Nothing is written and no partial
specification escapes.
Parameters
| Name | Type | Description |
|---|---|---|
text | char8[..] | the specification body, without the surrounding braces or the colon |
Returns: the parsed specification, or where it was malformed
RejectStyle
pub func RejectStyle(spec: FormatSpec) -> ! FormatError
Refuses a specification that names any style.
The parser recognizes a style wherever the grammar allows one; whether it means anything is the value's
question. A value with no styles of its own calls this so that {:q} is refused rather than silently rendered
as though nothing had been asked for.
Reports UnsupportedRequest when a style was written.
Parameters
| Name | Type | Description |
|---|---|---|
spec | FormatSpec | the specification to check |
Returns: success when no style was named
RejectNonBaseStyle
pub func RejectNonBaseStyle(spec: FormatSpec) -> ! FormatError
Refuses a specification whose style is not one of the integer bases.
What an integer supports is exactly b, o, x and X, and each of those is already reflected in Base.
So a style that left the base decimal is one this value has no meaning for, which is what this refuses. It is
the integer counterpart of RejectStyle and exists for the same reason.
Reports UnsupportedRequest for a style that names no base.
Parameters
| Name | Type | Description |
|---|---|---|
spec | FormatSpec | the specification to check |
Returns: success when no style was named, or the style named a base