Pular para o conteúdo

Stdlib · extensões

intl

internacionalização (i18n)

extensions.md · 69 linhas · 2 min de leitura

use intl

Em duas fases. Fase 1 (agora): o mínimo útil, com catálogo de mensagens, plural CLDR, e ganchos de formatação locale-aware reusando o locale que já existe no core. Fase 2 (esboçada): ICU completo, com collation, segmentação (grapheme/word/line break), bidi, calendários não-gregorianos, transliteração, ranges/listas formatados. Tier 1.

decl Locale { ... } // "pt-BR", "en-US" (BCP 47); estende o locale do core
fn locale_of(tag: string) -> Result[Locale, error{Malformed}]
fn (l: Locale) language() -> string // "pt"
fn (l: Locale) region() -> Optional[string] // "BR"
// catálogo de mensagens: lookup por chave + locale
decl Catalog { ... }
fn (Catalog) load(messages: Map[string, string], locale: Locale) -> Catalog
fn (c: Catalog) get(key: string) -> Optional[string]
fn (c: Catalog) format(key: string, args: Map[string, string]) -> string // interpola {{nome}} (§16)
// regras de plural (CLDR): escolhe a categoria certa para o número no locale
decl PluralCategory { Zero; One; Two; Few; Many; Other }
fn (l: Locale) plural(n: i64) -> PluralCategory // pt: 1→One, resto→Other; ru/ar: regras ricas
fn (c: Catalog) plural(key: string, n: i64) -> string // escolhe a variante e interpola
// formatação locale-aware (ganchos sobre o locale do core)
fn (l: Locale) format_int(n: i64) -> string // separadores de milhar/decimal do locale
fn (l: Locale) format_float(x: f64, frac_digits: u32) -> string
fn (l: Locale) format_currency(amount: i64, currency: string) -> string // "R$ 1.234,56" / "$1,234.56"
fn (l: Locale) format_date(t: DateTime, style: DateStyle) -> string // estilos nomeados (sem layout mágico)
decl DateStyle { Short; Medium; Long; Full }
use intl
cat := intl.Catalog.load(mensagens_pt, intl.locale_of("pt-BR").or_panic())
msg := cat.plural("itens_no_carrinho", n) // "1 item" / "3 itens", categoria certa pelo CLDR
preco := intl.locale_of("pt-BR").or_panic().format_currency(123456, "BRL") // "R$ 1.234,56"

Superfície prevista, implementação adiada (cada uma puxa tabelas Unicode/CLDR pesadas, opt-in puro):

fn (l: Locale) collator() -> Collator // ordenação alfabética localizada (collation)
fn (c: Collator) compare(a: string, b: string) -> Order
fn graphemes(s: string) -> Iterator[string] // segmentação por grapheme cluster
fn words(s: string, l: Locale) -> Iterator[string] // segmentação por palavra (locale-aware)
fn line_breaks(s: string) -> Iterator[usize] // pontos de quebra de linha (UAX 14)
fn (s: string) to_bidi(l: Locale) -> string // reordenação bidirecional (UAX 9)
fn transliterate(s: string, scheme: string) -> string // "Greek-Latin", etc.
// + calendários não-gregorianos, formatação de range/lista, etc.
  • Duas fases, opt-in: fase 1 cobre 90% (catálogo + plural + format) reusando o locale do core; fase 2 (ICU) é o universo pesado, escrito como superfície agora, implementado quando precisar. As tabelas Unicode/CLDR só pesam pra quem importa.
  • Reusa o locale/unicode do core: intl é a camada de políticas locale-aware; os dados e o mecanismo Unicode vêm de baixo (tier 0), coerente com o corte mecanismo-vs-dado dos tiers (§1).
  • Sem format string mágica: estilos nomeados (DateStyle) + interpolação (§16), como time.