unicode

UTF-8 and Unicode segmentation support for String's Character layer.

_utf8_decode returns one packed Int: scalar * 8 + size, where size is the number of bytes consumed (1-4). Packing avoids a per-scalar record allocation on the hot iteration path.

Ill-formed input consumes a maximal subpart (Unicode 17.0 §3.9.6, the same policy as Rust's fromutf8lossy and WHATWG): a truncated-but-valid prefix is one error unit, a lone continuation or invalid lead is one byte. Error units decode as U+FFFD for classification, but callers keep viewing the raw bytes — iteration over any byte string is lossless.

API Reference

Structs

struct Character

One extended grapheme cluster, represented as a borrowed UTF-8 byte range.

struct CharacterIterator

Walks extended grapheme clusters across a borrowed UTF-8 range.

struct ScalarIterator

Walks Unicode scalar values across a borrowed UTF-8 range.

Globals

let _WB_OTHER: Int

Internal code for UAX #29 word-break category Other.

let _WB_CR: Int

Internal code for UAX #29 word-break category CR.

let _WB_LF: Int

Internal code for UAX #29 word-break category LF.

let _WB_NEWLINE: Int

Internal code for UAX #29 word-break category Newline.

let _WB_EXTEND: Int

Internal code for UAX #29 word-break category Extend.

let _WB_ZWJ: Int

Internal code for UAX #29 word-break category ZWJ.

let _WB_FORMAT: Int

Internal code for UAX #29 word-break category Format.

let _WB_KATAKANA: Int

Internal code for UAX #29 word-break category Katakana.

let _WB_ALETTER: Int

Internal code for UAX #29 word-break category ALetter.

let _WB_MIDNUM: Int

Internal code for UAX #29 word-break category MidNum.

let _WB_NUMERIC: Int

Internal code for UAX #29 word-break category Numeric.

Functions

func _utf8_decode(storage: ByteStorage, offset: Int, end: Int) -> Int

Decodes one UTF-8 scalar and packs its value with the consumed byte count. Malformed input yields U+FFFD and consumes one maximal invalid subpart.

func _grapheme_category(scalar: Int) -> Int

The scalar's grapheme-cluster-break category (a GC* constant), via binary search over the generated boundary list. O(log n) with ~12 probes; ASCII short-circuits.

func scalar_is_digit(scalar: Int) -> Bool

Tests whether Unicode assigns the scalar decimal or digit numeric status.

func _compose_pair(starter: Int, combining: Int) -> Int?

Looks up canonical composition for a starter and following combining scalar.

func _next_boundary(storage: ByteStorage, offset: Int, end: Int) -> Int

The byte offset just past the extended grapheme cluster starting at offset, which must itself be a cluster boundary. Because scans start at true boundaries, all UAX #29 rule state (GB11's emoji sequence, GB9c's conjunct chain, GB12/13's regional-indicator parity) is local to this one scan — the iterator carries none.