Skip to main content

Crate mf2

Crate mf2 

Source
Expand description

mf2 — Unicode MessageFormat 2 for Rust applications: Leptos web applications, and native command-line and terminal applications. It is the crate an application names; beside it, the application’s build script names mf2-build.

What a tr! call site builds is a small description of a message — Tr, TrArgs, TrRich, TrDyn — and nothing is formatted until something renders or stringifies it. The descriptions and their arguments (ArgValue, converted from the call site’s values through IntoArg) are defined here, once, with every integration added behind a feature:

FeatureAdds
(core)the descriptions, formatted against a Formatter the caller builds; mf2_runtime’s formatter: :string, :number / :integer / :offset with neutral symbols, markup, bidi, fallback
leptos / leptos-0-8the Leptos line the layer renders with: Leptos 0.9 (the default line) or 0.8
ssr, hydrate, csrthe Leptos layer, leptos: rendering in text, attributes and props, the catalog of the request or of the page, the live switch, the page’s components; each mode implies its host
static-localea locale switch is a cookie and a navigation (for islands)
mark-fallback-langtext borrowed from a fallback language is marked with its own lang
nativenative: a native application — a command-line tool, a terminal UI — with its catalogs embedded or beside the executable, installed once for the process, in the system’s language and time zone; the descriptions’ Display, to_string() and to_cow() read them (std; implies host-std; beside hydrate or csr, refused when compiling for wasm32)
ratatuiratatui: a terminal UI’s text — a message as Ratatui Text or Line, its markup as styles (implies native; ratatui-core alone; beside hydrate or csr, refused when compiling for wasm32)
compilecompile_str: an ad-hoc message as a one-message catalog (std; servers and tests)
fn-numberfn_number: :number / :integer / :offset localized, :percent, localized unannotated numbers
fn-datetimefn_datetime: :datetime / :date / :time, unannotated date/time values (Registry::with_dates) — over the neutral stub backend until a backend is on; with a Leptos mode, also dates in the reader’s time zone
datetime-icuICU4X on client and server, data from the catalog’s icu.blob (and compile_str emits it)
datetime-intlthe browser’s Intl.DateTimeFormat on wasm32-unknown-unknown; ICU4X with compiled data elsewhere
host-std / host-weba Host: native (and wasm32-wasip1), or the browser
intlon wasm32-unknown-unknown (INTL_NUMBERS): numbers and plural selection through the browser’s Intl (host_web::NUMBERS_HOST); the Rust path elsewhere

A Leptos mode needs a line, and the modes exclude each other: an application writes the line on its mf2 dependency (features = ["leptos"]) and the mode where it writes Leptos’s own (ssr = ["leptos/ssr", "mf2/ssr"]). This documentation shows ssr on Leptos 0.9, and native and ratatui, which compile beside it; leptos lists what the client modes add. host-web and intl are for wasm32-unknown-unknown, so host_web is not shown here. A native application turns on native (a terminal UI, ratatui), and no Leptos mode.

A build with no mode compiles no Leptos code, so a server and a test use the descriptions as they are: formatted against a catalog the caller supplies. A native application installs its catalogs with native, and its descriptions then show their text wherever text is wanted (println!("{}", tr!("welcome"))).

use mf2::{Arg, FormatContext, Formatter, Registry, functions};

static FUNCTIONS: [(&str, &dyn mf2::Function); 1] = [("integer", &functions::INTEGER)];
static REGISTRY: Registry = Registry::new(&FUNCTIONS);
static CX: FormatContext = FormatContext::new(&mf2::host_std::HOST);

let m = mf2::compile_str(
    ".input {$n :integer} .match $n one {{{$n} item}} * {{{$n} items}}",
    "en",
)
.unwrap();
let f = Formatter::new(&m.catalog, &REGISTRY, &CX);
let mut out = String::new();
let mut errors = Vec::new();
f.write(mf2::Compiled::ID, &[Arg::Int(3)], &mut out, &mut errors);
assert_eq!(out, "3 items");
assert!(errors.is_empty());

With fn_datetime, a date: a handler over a chosen backend (here the neutral stub; DATETIME and DATES are these over the default one) and the registry that formats unannotated date/time values with it.

use mf2::fn_datetime::{DateTimeFunction, Neutral};
use mf2::{FormatContext, Formatter, Registry};

static DATETIME: DateTimeFunction<Neutral> = DateTimeFunction::datetime(Neutral);
static DATES: DateTimeFunction<Neutral> = DateTimeFunction::unannotated(Neutral);
static FUNCTIONS: [(&str, &dyn mf2::Function); 1] = [("datetime", &DATETIME)];
static REGISTRY: Registry = Registry::new(&FUNCTIONS).with_dates(&DATES);
static CX: FormatContext = FormatContext::new(&mf2::host_std::HOST);

let m = mf2::compile_str("{|2006-01-02T15:04:06| :datetime timePrecision=second}", "en").unwrap();
let mut out = String::new();
let mut errors = Vec::new();
Formatter::new(&m.catalog, &REGISTRY, &CX).write(mf2::Compiled::ID, &[], &mut out, &mut errors);
assert_eq!(out, "2006-01-02 15:04:06");
assert!(errors.is_empty());

§The user guide

The Rust MF2 book is the user guide: how the crates fit together, web and native applications, the command line, and what 2.x promises.

Re-exports§

pub use leptos::Flat;csr or hydrate or ssr
pub use leptos::FlatHandler;csr or hydrate or ssr
pub use leptos::NestingHandler;csr or hydrate or ssr
pub use leptos::SignalArg;csr or hydrate or ssr
pub use leptos::signal_arg;csr or hydrate or ssr
pub use mf2_fn_number as fn_number;fn-number
pub use mf2_fn_datetime as fn_datetime;fn-datetime
pub use mf2_host_std as host_std;host-std

Modules§

axumaxum
An Axum server’s side of Rust MF2, with or without Leptos: locale negotiation, the catalogs served from the server binary, and the generated Locale as an extractor.
functions
The core functions (plans/03-runtime.md §3, §5.1): statics for a crate::Registry. An application’s generated registry names only the ones its corpus uses (closed world, B13).
leptoscsr or hydrate or ssr
The Leptos layer: how a description renders — in text, attributes and props — together with the catalog of the request or of the page, the live locale switch, <html lang dir>, the page’s i18n components and the reader’s time zone for dates.
nativenative
A native application’s messages — a command-line tool or a terminal UI, with no Leptos: one generated corpus’s catalogs for the whole process, the reader’s language chosen from the system’s, and the descriptions tr! builds shown in it.
ratatuiratatui
Ratatui text from a native application’s messages, their markup as styles.

Macros§

include_generated
Includes what mf2-build wrote into OUT_DIR: the manifest hash, the locale table, the closed-world registry, the host, __mf2 and the tr! wrapper. An i18n crate’s whole src/lib.rs is

Structs§

ArgList
The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The values of a call site, in slot order: up to four inline — the reference workload’s maximum — and a boxed slice beyond that. Never a const generic: one concrete type, whatever the arity.
Catalog
A validated .mf2b catalog (F2): the fetched buffer and the offsets new found. Share it as Rc<Catalog> / Arc<Catalog>.
CatalogFile
One locale’s compiled catalog: its file name and, when the build embedded it (Emit::Native), its bytes.
Compiledcompile
A compiled message: its one-message catalog and the catalog’s manifest.
Corpus
A corpus as a native build generates it: the generated module’s CORPUS. Never written by hand; read it through its methods.
Date
A civil date in the proleptic Gregorian calendar (ISO 8601).
DateStyle
The date part: dateFields / fields and dateLength / length.
DateTime
A date/time value: an application’s argument (crate::Arg::DateTime, crate::CustomValue::as_date_time), a literal a date/time function parsed, or what :datetime, :date or :time resolved — the value with its DateTimeOptions. Build it with the constructors.
DateTimeOptions
What :datetime, :date or :time resolved (datetime.md). The override options (time_zone, hour12, calendar) travel with the value into a later date/time expression that takes it as its operand.
DateTimeRequest
What a host’s date formatter receives (Host::format_date_time, datetime-intl): an instant and how to show it.
DateTimeValue
The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. A date/time a call site owns: Arg::DateTime with its zone and calendar owned.
DigitOptions
ECMA-402’s digit options as SetNumberFormatDigitOptions resolved them for MF2 — so never a set Intl rejects: where it would throw, the numeric function reported Bad Option and dropped or replaced the option (plans/03-runtime.md §5.3).
Digits
Digits to show (plans/03-runtime.md §2.7): a resolved number’s rounded display digits (Number::digits), or a number’s exact value (Number::exact_digits) — what mf2-fn-number localizes.
ExpressionPart
A formatted placeholder: its resolved value and how it formats.
FnContext
What a handler may see of the formatting context: read-only and minimal (formatting.md, “Function Handler”).
FormatContext
What formatting needs beyond the catalog and the registry; build it with FormatContext::new.
Formatter
Formats messages of one catalog.
Handler
A MarkupHandler the caller wrote, on its way through [markup].
LanguageMatching
CLDR’s language-matching data — likely subtags, the rules of the three levels and their match variables, the paradigm locales — in the form the matcher reads: all of it (a server’s), or the part one corpus needs, which the build cuts and the generated module holds as LANGUAGE_MATCHING (what a native application’s corpus and a client-only application’s setup carry).
MarkupOptions
The options of a MarkupPart: (name, value) in source order.
MarkupPart
A markup placeholder.
Measure
A number with a currency or a unit, and the options its function added.
MsgId
A message id: which message of a build’s catalogs. tr! and the generated module make them; an application compares, hashes and passes them, and never builds one from a number.
NoErrors
Discards errors: the release client’s policy (plans/03-runtime.md §8).
Number
An exact decimal and, once a numeric handler resolved it, its resolved options and its display form. Opaque: the digit backend is internal (owner decision 1).
NumberRequest
A number for a NumberFormatter (the host’s, Host::numbers). Built by the runtime; a host reads it.
NumberSpec
How one numeric function resolves (plans/03-runtime.md §2.7): which options it reads, its fraction-digit defaults, whether it rounds to an integer, whether it selects, and the power of ten it applies. Closed world: a handler is a spec.
Operands
The UTS #35 operands of a non-negative decimal (Part 3 §5.1.1): the formatter’s side of the contract of plans/02-catalog-format.md §4.1. n is integral iff t == 0, and then equals i.
OptionValue
A resolved option value.
Options
The resolved options passed to Function::resolve. Their order is not significant; a repeated name (a Duplicate Option Name, which the build rejects) resolves to the last.
Registry
The function handlers an application links: closed world (B13). Build code generates it from exactly the functions the corpus uses, e.g. static REGISTRY: Registry = Registry::new(&[("integer", &mf2_runtime::functions::INTEGER)]); — an unused handler is never referenced, so never linked.
Time
A wall-clock time, to the millisecond (a date/time literal has at most three fraction digits).
TimeZone
The formatting context’s time zone: the default of timeZone (plans/03-runtime.md §6). Owned — a per-request zone need not be 'static.
Tr
A message with no arguments: the whole call site is these four bytes.
TrArgs
A message with arguments: one concrete type, whatever the arity, so that a call site instantiates no generic.
TrDyn
A message and its arguments by name, matched against the catalog’s NAMES when it formats — including the names the message does not have.
TrRich
A message rendered with its markup as elements: the arguments, plus one type-erased handler per markup name of the message, found by the hash of that name — the name itself never reaches the wasm.
UnknownLocale
Why a generated Locale::from_str refused a tag: none of the application’s languages serves it (plans/19-native-and-terminal.md §9, §10). Its text lists the languages there are — “no language of this application matches; it has en, fr” — which is what clap shows for a refused --lang. It allocates nothing: it holds the build’s own table.

Enums§

Arg
A positional argument: slot i of the call site is args[i] (the manifest’s slot order). Small on purpose: every variant is a code path in the wasm. Non-exhaustive, so variants can be added.
ArgValue
The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. One positional argument of a call site: owned, 'static and Send + Sync, so a description can sit in a const, cross a thread, or wait in a registry until something renders it.
BidiStrategy
A bidirectional isolation strategy (formatting.md, “Handling Bidirectional Text”).
CatalogError
Why crate::Catalog::new rejected a buffer (F4, F6, F9).
Category
A CLDR plural category.
CompileErrorcompile
Why crate::compile_str refused a message.
CurrencyDisplay
:currency’s currencyDisplay.
DateFields
dateFields / fields.
DateLength
dateLength / length.
Dir
Text direction.
ErrorKind
The kind of an MF2 error: the 13 error types of the WG test suite (test/README.md, “Error Codes”) plus Unsupported Operation and the umbrella Message Function Error of spec/errors.md.
FallbackSource
What a fallback value shows (formatting.md, “Fallback Resolution”).
FormatError
An error reported while formatting. Formatting still produces output.
Grouping
useGrouping. Core output never groups; mf2-fn-number honours it.
Isolation
A bidi isolation control.
MarkupKind
The three forms of markup.
MeasureUnit
What a Measure measures.
NumberOut
Where NumberFormatter::format writes: text, or sub-parts (formatToParts: integer, group, decimal, fraction, minusSign, plusSign, percentSign, currency, unit, literal, …).
NumberStyle
How a NumberRequest is shown.
Part
A part of a formatted message. Concatenated, the parts are the string output.
RoundingMode
roundingMode (ECMA-402’s names and meanings).
RoundingPriority
roundingPriority.
Sign
The sign a formatted number shows, after signDisplay.
SignDisplay
signDisplay.
Text
The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. Text a call site owns: a literal costs nothing, anything else is counted, so cloning a description — which every re-format after a locale change does — never copies the text.
TimePrecision
timePrecision / precision.
UnitDisplay
:unit’s unitDisplay.
Value
A resolved value’s data. The handler that resolved it decides how it formats and selects; a value no handler resolved (a literal, an argument) is unannotated (plans/03-runtime.md §2.6).
ZoneOption
A time zone as an option value (timeZone) or a formatting target.
ZoneStyle
timeZoneStyle.

Traits§

ArgSource
The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. The call-site core: what tr! builds, and what formats it against a catalog the caller supplies. A value read at format time — the extension point for a reactive argument.
CustomValue
An application’s own argument type: what it converts to.
ErrorSink
An error sink.
Function
A function handler. :string, :number, :integer, :offset are in crate::functions; custom functions implement the same trait (the suite’s :test:* functions are written against it).
Host
The platform services the runtime needs.
IntoArg
A value a tr! argument converts from, by its type: a number, a string, a date, a path, or an application’s own type.
IntoMarkupHandler
What [markup] accepts.
MarkupHandler
A markup handler, as the core carries it: the rendering layer’s own type, erased.
Message
A call-site description tr! builds: formatted to text, or to parts.
NumberFormatter
A number formatter for the intl option (Host::numbers; plans/03-runtime.md §2.7, §5.3): the final “value + resolved options → text” step and the plural category, where the numeric functions keep MF2’s semantics in Rust. mf2-host-web implements it with Intl.
PartSink
Receives the parts of a formatted message, in order.
Sink
A text sink.
SubPartSink
Receives the sub-parts of a formatted expression (a number’s minusSign, integer, decimal, fraction, …).

Functions§

compile_strcompile
Compiles MF2 source for locale into a one-message catalog: parse, validate (syntax and data-model errors refuse the message, with their kinds), analyze the variables (the slots), and write it with the locale’s direction, plural rules (both kinds) and number data (CLDR 48.2.1): number.symbols always — any placeholder can receive a number, which fn-number localizes — and what the message’s numeric functions need by the slicing rule of plans/02-catalog-format.md §4.4: the patterns, and the currencies and units its literal options name (a variable option value: all of them). With datetime-icu, also the icu.blob of what the message formats with the date functions, or can receive as a date/time argument (a placeholder whose variable has no function), by the same rule, for every variant of the ICU4X backend.
compile_str_strippedcompile
compile_str, with the catalog in its production form: COLD and IDS stripped (plans/02-catalog-format.md §2.3). It formats identically.
is_zone_name
Whether s is a well-formed RFC 9557 time-zone-name: parts separated by /, each starting with a letter, . or _, then letters, digits, ., _, - or +, and neither . nor ...