Skip to content

stdlib.string

String Library

Generated from v0.60.1. 69 source files, 413 documented symbols.

align.xi

fn str_align_left(s: Str, width: Int) -> Str

Left-aligns s in a field of width bytes, padding on the right with spaces. A string already at or over the width is returned unchanged; a negative width is rejected (returns s). Params: s the source string; width the field width in bytes. Returns: the left-aligned string. Error case: none; width < 0 is a no-op. Complexity: O(width).

  • Postcondition: width < 0 => result == s
fn str_align_right(s: Str, width: Int) -> Str

Right-aligns s in a field of width bytes, padding on the left with spaces. A string already at or over the width is returned unchanged; a negative width is rejected (returns s). Params: s the source string; width the field width in bytes. Returns: the right-aligned string. Error case: none; width < 0 is a no-op. Complexity: O(width).

  • Postcondition: width < 0 => result == s
fn str_align_center(s: Str, width: Int) -> Str

Centers s in a field of width bytes, padding both sides with spaces; when the padding does not split evenly the extra space goes on the right. A string already at or over the width is returned unchanged; a negative width is rejected (returns s). Params: s the source string; width the field width in bytes. Returns: the centered string. Error case: none; width < 0 is a no-op. Complexity: O(width).

  • Postcondition: width < 0 => result == s
fn str_align_justify(s: Str, width: Int) -> Str

Justifies s to width bytes by distributing the extra space between the words: gaps are padded from left to right, so earlier gaps may receive one extra space. When there is only one word, or the words already fill the width, or width is negative, s is returned unchanged. Params: s the source string; width the target width in bytes. Returns: the justified string. Error case: none; width < 0 is a no-op. Complexity: O(|s| + width).

  • Postcondition: width < 0 => result == s



bidi.xi

fn unicode_bidi_class(c: Char) -> Str

Bidirectional class of c (two- or three-letter code per UAX #9): "L", "R", "AL", "EN", "AN", "ES", "ET", "CS", "NSM", "WS", "B", "S", "BN", "LRE", "LRO", "RLE", "RLO", "PDF", "ON". Unmapped codepoints report "L". Params: c the character to classify. Returns: the bidi class code. Error case: none. Complexity: O(1).

fn unicode_mirrored(c: Char) -> Bool

True when c has the Bidi_Mirrored property, i.e. it has a mirrored counterpart used when the text direction flips (brackets, angle brackets, curly braces, and a few quotes/guillemets). Unmapped codepoints are not mirrored. Params: c the character to test. Returns: true when c is mirrored. Error case: none. Complexity: O(1).

fn unicode_mirror_char(c: Char) -> Char

Mirror image of c: the paired bracket/quote on the other side, or c itself when c is not mirrored. E.g. '(' -> ')', ')' -> '(', '[' -> ']', '{' -> '}', '<' -> '>', '<<' -> '>>', '<' -> '>'. Params: c the character to mirror. Returns: the mirrored counterpart, or c itself. Error case: none. Complexity: O(1).




block.xi

fn unicode_block(c: Char) -> Str

Returns the Unicode block name of the character c, e.g. 'A' yields "Basic Latin" and 'Omega' yields "Greek and Coptic". Code points outside every known block yield "Undefined". Params: c the character to classify. Returns: the block name. Error case: none. Complexity: O(number of table entries).

fn unicode_block_name(code: Str) -> Str

Returns the Unicode block name for the block code given as a code-point hex string. Accepted forms: bare hex ("41", "1F600"), "0x..." and "U+..." prefixed, and "\u" escaped. Invalid or non-hex input yields "Undefined". Params: code the code point as a hex string. Returns: the block name, or "Undefined" when unparsable/unmapped. Error case: "Undefined" for empty, non-hex, or unmapped input. Complexity: O(|code| + number of table entries).

  • Precondition: true



builder.xi

fn sb_new() -> Vec[UInt8]

New empty builder. Complexity: O(1).

  • Postcondition: result.len() == 0
fn sb_push_byte(sb: &mut Vec[UInt8], b: UInt8)

Append one byte. Complexity: O(1) amortized.

  • Postcondition: sb.len() >= 1
fn sb_push_str(sb: &mut Vec[UInt8], s: Str)

Append a whole string (byte copy; UTF-8 safe -- bytes are opaque here). Complexity: O(s.len()) amortized.

  • Postcondition: s.len() > 0 => sb.len() >= 1
fn sb_push_int(sb: &mut Vec[UInt8], v: Int)

Append the decimal representation of v (sign-aware, zero-safe). Emits digits without any temporary Str allocation. Complexity: O(digits).

  • Postcondition: sb.len() >= 1
fn sb_to_str(sb: &Vec[UInt8]) -> Str

Materialize the built string: single allocation, ownership of the fresh NUL-terminated buffer moves into the result Str ([XFER]). The builder vector is untouched and remains usable. Complexity: O(n).

  • Postcondition: result.len() == sb.len()
fn sb_clear(sb: &mut Vec[UInt8])

Reset to empty. Complexity: O(n).

  • Postcondition: sb.len() == 0



case.xi

fn str_upper(s: Str) -> Str

Converts all characters of s to uppercase. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_lower(s: Str) -> Str

Converts all characters of s to lowercase. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_title(s: Str) -> Str

Capitalizes the first letter of every word of s; remaining characters of each word are lowercased. Whitespace and separators are preserved. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_swap_case(s: Str) -> Str

Swaps the case of every letter in s; characters that are neither uppercase nor lowercase are left unchanged. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_capitalize(s: Str) -> Str

Uppercases the first character of s and lowercases the rest. Returns s unchanged when s is empty. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_sentence_case(s: Str) -> Str

Capitalizes the first letter of each sentence of s. A sentence boundary is a '.', '!' or '?' character; the next alphabetic character is uppercased. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_to_camel_case(s: Str) -> Str

Converts s to lowerCamelCase: the first word is lowercased and each following word is capitalized; separators are dropped. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn str_to_snake_case(s: Str) -> Str

Converts s to snake_case: words are lowercased and joined with '_'. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn str_to_kebab_case(s: Str) -> Str

Converts s to kebab-case: words are lowercased and joined with '-'. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn str_to_pascal_case(s: Str) -> Str

Converts s to PascalCase: every word is capitalized and joined without a separator. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0



casefold.xi

fn str_casefold(s: Str) -> Str

Full Unicode case folding of s for case-insensitive comparison. ASCII, Latin-1, Latin Extended-A, Greek and Cyrillic uppercase letters are folded to their lowercase forms; the sharp s (ss/SS) folds to "ss" and dotted capital I (I) folds to "i" + combining dot, matching the Unicode full case-folding mapping for those characters. Params: s the string to fold. Returns: the case-folded string. Error case: none; malformed UTF-8 bytes pass through unchanged. Complexity: O(|s|).

fn str_casefold_ascii(s: Str) -> Str

ASCII-only case folding of s: 'A'..'Z' become lowercase, every other byte is copied verbatim. No Unicode tables are consulted. Params: s the string to fold. Returns: the ASCII-folded string. Error case: none. Complexity: O(|s|).




category.xi

fn unicode_general_category(c: Char) -> Str

Two-letter Unicode general category of c, e.g. "Lu", "Ll", "Nd", "Zs", "Po". Unmapped codepoints report "Cn" (Other/unassigned). Params: c the character to classify. Returns: the two-letter general category code. Error case: none. Complexity: O(1).

fn unicode_is_letter(c: Char) -> Bool

True when c is a letter (categories Lu, Ll, Lt, Lm, Lo). Params: c the character to test. Returns: true when c is a letter. Error case: none. Complexity: O(1).

fn unicode_is_digit(c: Char) -> Bool

True when c is a decimal digit (category Nd). Params: c the character to test. Returns: true when c is a decimal digit. Error case: none. Complexity: O(1).

fn unicode_is_punct(c: Char) -> Bool

True when c is punctuation (categories Pc, Pd, Ps, Pe, Pi, Pf, Po). Params: c the character to test. Returns: true when c is punctuation. Error case: none. Complexity: O(1).

fn unicode_is_symbol(c: Char) -> Bool

True when c is a symbol (categories Sm, Sc, Sk, So). Params: c the character to test. Returns: true when c is a symbol. Error case: none. Complexity: O(1).

fn unicode_is_separator(c: Char) -> Bool

True when c is a separator (categories Zs, Zl, Zp). Params: c the character to test. Returns: true when c is a separator. Error case: none. Complexity: O(1).

fn unicode_is_control(c: Char) -> Bool

True when c is a control or format character, or otherwise falls in the "Other" (C) group: Cc, Cf, Cs (surrogates), Co (private use) or Cn (unassigned). The inverse of unicode_is_printable. Params: c the character to test. Returns: true when c is in category Cc/Cf/Cs/Co/Cn. Error case: none. Complexity: O(1).

fn unicode_is_printable(c: Char) -> Bool

True when c is printable, i.e. not a control/format character and not in the "Other" (C) group. Letters, marks, numbers, punctuation, symbols and separators are printable. Params: c the character to test. Returns: true when c is printable. Error case: none. Complexity: O(1).




char.xi

fn is_alphabetic(c: Char) -> Bool

True when the character is alphabetic.

  • Postcondition: result == ((to_int_from_char(c) >= 65 && to_int_from_char(c) <= 90) || (to_int_from_char(c) >= 97 && to_int_from_char(c) <= 122))

fn is_alphanumeric(c: Char) -> Bool

True when the character is alphabetic or numeric.

  • Postcondition: result == (is_alphabetic(c) || is_digit(c))

fn is_ascii(c: Char) -> Bool

True when the code point is below 128.

  • Postcondition: result == (to_int_from_char(c) <= 127)

fn is_control(c: Char) -> Bool

True when the character is a control code.

  • Postcondition: result == ((to_int_from_char(c) >= 0 && to_int_from_char(c) <= 31) || to_int_from_char(c) == 127)

fn is_digit(c: Char) -> Bool

True when the character is an ASCII decimal digit.

  • Postcondition: result == (to_int_from_char(c) >= 48 && to_int_from_char(c) <= 57)

fn is_lowercase(c: Char) -> Bool

True when the character is lowercase.

  • Postcondition: result == (to_int_from_char(c) >= 97 && to_int_from_char(c) <= 122)

fn is_uppercase(c: Char) -> Bool

True when the character is uppercase.

  • Postcondition: result == (to_int_from_char(c) >= 65 && to_int_from_char(c) <= 90)

fn is_numeric(c: Char) -> Bool

True when the character is numeric.

  • Postcondition: result == is_digit(c)

fn is_punctuation(c: Char) -> Bool

True when the character is punctuation.

  • Postcondition: result == ((to_int_from_char(c) >= 33 && to_int_from_char(c) <= 47) || (to_int_from_char(c) >= 58 && to_int_from_char(c) <= 64) || (to_int_from_char(c) >= 91 && to_int_from_char(c) <= 96) || (to_int_from_char(c) >= 123 && to_int_from_char(c) <= 126))

fn is_whitespace(c: Char) -> Bool

True when the character is whitespace.

  • Postcondition: result == (to_int_from_char(c) == 32 || to_int_from_char(c) == 9 || to_int_from_char(c) == 10 || to_int_from_char(c) == 13)

fn to_lowercase(c: Char) -> Char

Lowercase mapping of the character.

fn to_uppercase(c: Char) -> Char

Uppercase mapping of the character.

fn to_digit(c: Char, radix: Int) -> Option[Int]

Numeric value in the given radix (2..36), or None.

  • Postcondition: radix < 2 || radix > 36 => result is None
  • Postcondition: result is Some(_) => result.value >= 0

fn from_digit(n: Int, radix: Int) -> Option[Char]

Character for a digit value in the given radix, or None.

  • Postcondition: n < 0 || n >= radix => result is None
  • Postcondition: radix < 2 || radix > 36 => result is None

fn len_utf8(c: Char) -> Int

UTF-8 encoding length of the character (1..4).

  • Postcondition: result >= 1 && result <= 4

fn encode_utf8(c: Char, buf: &mut Vec[UInt8])

Append the UTF-8 encoding of the character to buf.

fn is_letter(c: Char) -> Bool

Alias for is_alphabetic. Returns true if c is an ASCII letter (a-z, A-Z).

  • Postcondition: result == is_alphabetic(c)

fn is_control_char(c: Char) -> Bool

Alias for is_control. Returns true if c is a C0 control character or DEL.

  • Postcondition: result == is_control(c)

fn is_hex_digit(c: Char) -> Bool

Returns true if c is a hexadecimal digit (0-9, a-f, A-F).

  • Postcondition: result == ((to_int_from_char(c) >= 48 && to_int_from_char(c) <= 57) || (to_int_from_char(c) >= 65 && to_int_from_char(c) <= 70) || (to_int_from_char(c) >= 97 && to_int_from_char(c) <= 102))

fn is_binary_digit(c: Char) -> Bool

Returns true if c is a binary digit ('0' or '1').

  • Postcondition: result == (c == '0' || c == '1')

fn is_octal_digit(c: Char) -> Bool

Returns true if c is an octal digit ('0' through '7').

  • Postcondition: result == (c >= '0' && c <= '7')

fn is_symbol(c: Char) -> Bool

Returns true if c is a symbol character (punctuation, currency, math, or modifier). Covers ASCII punctuation + common Unicode symbol ranges.

  • Postcondition: result == (is_currency(c) || is_math_symbol(c) || is_punctuation(c) || (to_int_from_char(c) >= 160 && to_int_from_char(c) <= 191) || (to_int_from_char(c) >= 215 && to_int_from_char(c) <= 247) || (to_int_from_char(c) >= 8208 && to_int_from_char(c) <= 8231) || (to_int_from_char(c) >= 8240 && to_int_from_char(c) <= 8286) || (to_int_from_char(c) >= 8592 && to_int_from_char(c) <= 8703) || (to_int_from_char(c) >= 8960 && to_int_from_char(c) <= 9215) || (to_int_from_char(c) >= 9472 && to_int_from_char(c) <= 9599) || (to_int_from_char(c) >= 9600 && to_int_from_char(c) <= 9631) || (to_int_from_char(c) >= 9632 && to_int_from_char(c) <= 9727) || (to_int_from_char(c) >= 9728 && to_int_from_char(c) <= 9983) || (to_int_from_char(c) >= 9984 && to_int_from_char(c) <= 10175))

fn is_currency(c: Char) -> Bool

Returns true if c is a currency symbol. Covers $, cent, pound, yen, and the currency symbols block U+20A0..U+20CF.

  • Postcondition: result == (to_int_from_char(c) == 36 || to_int_from_char(c) == 162 || to_int_from_char(c) == 163 || to_int_from_char(c) == 165 || (to_int_from_char(c) >= 8352 && to_int_from_char(c) <= 8399))

fn is_math_symbol(c: Char) -> Bool

Returns true if c is a mathematical symbol. Covers +, -, *, /, =, <, >, the plus-minus sign, and the mathematical operators block U+2200..U+22FF.

  • Postcondition: result == (c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '<' || c == '>' || to_int_from_char(c) == 177 || c == 'x' || (to_int_from_char(c) >= 8704 && to_int_from_char(c) <= 8959))

fn is_emoji(c: Char) -> Bool

Returns true if c falls within basic emoji code point ranges. Covers emoticons, miscellaneous symbols, transport, supplemental symbols.

  • Postcondition: result == ((to_int_from_char(c) >= 128512 && to_int_from_char(c) <= 128591) || (to_int_from_char(c) >= 127744 && to_int_from_char(c) <= 128511) || (to_int_from_char(c) >= 128640 && to_int_from_char(c) <= 128767) || (to_int_from_char(c) >= 129280 && to_int_from_char(c) <= 129535))

fn is_combining_mark(c: Char) -> Bool

Returns true if c is a combining diacritical mark (U+0300..U+036F).

  • Postcondition: result == (to_int_from_char(c) >= 768 && to_int_from_char(c) <= 879)

fn to_title_case(c: Char) -> Char

Returns the title-case version of c. For a single character this is equivalent to to_uppercase.

fn is_ascii_letter(c: Char) -> Bool

Returns true if c is an ASCII letter (a-z, A-Z).

  • Postcondition: result == is_alphabetic(c)

fn is_ascii_digit(c: Char) -> Bool

Returns true if c is an ASCII digit (0-9). Alias for is_digit.

  • Postcondition: result == is_digit(c)

fn is_ascii_hex_digit(c: Char) -> Bool

Returns true if c is an ASCII hexadecimal digit (0-9, a-f, A-F).

  • Postcondition: result == is_hex_digit(c)

fn is_ascii_punctuation(c: Char) -> Bool

Returns true if c is ASCII punctuation (codes 33-47, 58-64, 91-96, 123-126).

  • Postcondition: result == is_punctuation(c)

fn is_ascii_whitespace(c: Char) -> Bool

Returns true if c is ASCII whitespace (space, tab, newline, carriage return).

  • Postcondition: result == is_whitespace(c)

fn is_ascii_control(c: Char) -> Bool

Returns true if c is an ASCII control character (codes 0-31 or 127).

  • Postcondition: result == is_control(c)

fn is_ascii_graphic(c: Char) -> Bool

Returns true if c is an ASCII graphic character (codes 33-126, visible + space).

  • Postcondition: result == (to_int_from_char(c) >= 33 && to_int_from_char(c) <= 126)

fn is_ascii_printable(c: Char) -> Bool

Returns true if c is an ASCII printable character (codes 32-126, includes space).

  • Postcondition: result == (to_int_from_char(c) >= 32 && to_int_from_char(c) <= 126)

fn char_to_digit_value(c: Char) -> Option[Int]

Returns the numeric value (0-9) of a digit character, or None if c is not a digit.

fn digit_value_to_char(n: Int) -> Option[Char]

Returns the character representation of a single digit value n (0-9), or None if out of range.

fn is_uppercase_ascii(c: Char) -> Bool

Returns true if c is an uppercase ASCII letter (A-Z).

  • Postcondition: result == is_uppercase(c)

fn is_lowercase_ascii(c: Char) -> Bool

Returns true if c is a lowercase ASCII letter (a-z).

  • Postcondition: result == is_lowercase(c)

fn to_ascii_upper(c: Char) -> Char

Returns the ASCII uppercase version of c. If c is not a lowercase ASCII letter, it is returned unchanged.

  • Postcondition: result == to_uppercase(c)

fn to_ascii_lower(c: Char) -> Char

Returns the ASCII lowercase version of c. If c is not an uppercase ASCII letter, it is returned unchanged.

  • Postcondition: result == to_lowercase(c)

fn is_whitespace_or_separator(c: Char) -> Bool

Returns true if c is whitespace or a Unicode separator character. Covers ASCII whitespace + line/paragraph separators (U+2028, U+2029).

  • Postcondition: result == (is_whitespace(c) || to_int_from_char(c) == 8232 || to_int_from_char(c) == 8233)


chunk.xi

fn str_chunk(s: Str, n: Int) -> Vec[Str]

Splits s into consecutive chunks of n bytes; the final chunk may be shorter. A chunk size below 1 or an empty input yields an empty vector. Params: s the source string; n the chunk size in bytes. Returns: a Vec[Str] of chunks covering s exactly once. Error case: n < 1 or s.len() == 0 => empty vector. Complexity: O(s.len()).

fn str_chunks_reverse(s: Str, n: Int) -> Vec[Str]

Splits s into chunks of n bytes starting from the end; the remainder (if any) forms the first chunk. A chunk size below 1 or an empty input yields an empty vector. Params: s the source string; n the chunk size in bytes. Returns: a Vec[Str] of chunks in source order (first may be shorter). Error case: n < 1 or s.len() == 0 => empty vector. Complexity: O(s.len()).

fn str_windows(s: Str, n: Int) -> Vec[Str]

Returns all length-n overlapping substrings (windows) of s. A window size below 1 or larger than the input yields an empty vector. Params: s the source string; n the window size in bytes. Returns: a Vec[Str] with one element per start position 0..len-n. Error case: n < 1 or len < n => empty vector. Complexity: O(s.len()).




collate.xi

fn collate_compare(a: Str, b: Str) -> Int

Compare a and b in byte-wise collation order. Returns a negative Int when a sorts before b, zero when the strings are byte-identical, and a positive Int when a sorts after b. Bytes are compared unsigned, so bytes above 0x7F sort after ASCII on every platform. Params: a, b the strings to compare. Returns: negative / zero / positive per the byte-wise ordering of a vs b. Error case: none. Complexity: O(min(|a|, |b|)).

  • Postcondition: result >= -1 && result <= 1
fn collate_compare_numeric(a: Str, b: Str) -> Int

Compare a and b in natural collation order: embedded runs of ASCII digits are compared numerically rather than byte-wise, so "file2" sorts before "file10". Delegates to the proven natural-order comparator. Params: a, b the strings to compare. Returns: negative / zero / positive per the natural ordering of a vs b. Error case: none. Complexity: O(|a| + |b|).

fn collate_key(s: Str) -> Str

Collation key of s: an ASCII-case-folded copy such that comparing two keys with collate_compare reproduces the case-insensitive collation order of the original strings. Bytes above 0x7F pass through unchanged. Params: s the string to key. Returns: a key string whose byte-wise order matches the collation order. Error case: none. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()



combinatorics.xi

fn str_shuffle(s: Str) -> Str

Random permutation of the characters of s via Fisher-Yates, drawing swap indices from the runtime PRNG. The result is a rearrangement of the characters of s (same byte length); the order is not specified. Params: s the string to shuffle. Returns: a random permutation of the characters of s. Error case: none; the empty string maps to itself. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_shuffle_seeded(s: Str, seed: Int) -> Str

Deterministic shuffle of s using the given seed: the same seed always produces the same permutation via the Park-Miller sequence. The empty string maps to itself. Params: s the string to shuffle; seed the PRNG seed. Returns: the seeded permutation of s. Error case: none. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_shuffle_words(s: Str) -> Str

Random permutation of the whitespace-separated words of s. The result rejoins the shuffled words with single spaces; the original spacing runs are not preserved (see str_reverse_words for spacing preservation). Params: s the string whose words to shuffle. Returns: the shuffled words joined by single spaces. Error case: none; a string with no words yields "". Complexity: O(|s|).

fn str_shuffle_words_seeded(s: Str, seed: Int) -> Str

Deterministic word shuffle of s using the given seed. Params: s the string whose words to shuffle; seed the PRNG seed. Returns: the seeded permutation of the words of s. Error case: none; a string with no words yields "". Complexity: O(|s|).

fn str_rotate(s: Str, n: Int) -> Str

Rotate s right by n byte positions: a positive n moves characters toward the end of the string ("abcde" rotated right by 2 is "deabc"). A negative n rotates left. Rotating by a multiple of |s| returns s. Params: s the string to rotate; n the rotation amount in bytes. Returns: the rotated string. Error case: none; the empty string is returned unchanged. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_rotate_left(s: Str, n: Int) -> Str

Rotate s left by n byte positions ("abcde" rotated left by 2 is "cdeab"). A negative n rotates right. Params: s the string to rotate; n the rotation amount in bytes. Returns: the rotated string. Error case: none; the empty string is returned unchanged. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_rotate_right(s: Str, n: Int) -> Str

Rotate s right by n byte positions; identical to str_rotate and kept as the explicit right-rotation entry point. Params: s the string to rotate; n the rotation amount in bytes. Returns: the rotated string. Error case: none; the empty string is returned unchanged. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_rotate_word(s: Str, n: Int) -> Str

Rotate the whitespace-separated words of s by n positions: a positive n moves words toward the end. The result rejoins the rotated words with single spaces. Params: s the string whose words to rotate; n the rotation amount in words. Returns: the word-rotated string. Error case: none; a string with no words yields "". Complexity: O(|s|).

fn str_permutations(s: Str) -> Vec[Str]

All permutations of the characters of s, treating the characters as distinct (n! results for |s| = n; duplicate characters yield duplicate permutations). An empty string yields a vector containing "". The permutations are emitted in lexicographic byte order. Params: s the source string. Returns: a Vec[Str] with n! permutations. Error case: inputs longer than 8 characters return an empty vector (documented guard against an impractical 8!+ result set). Complexity: O(n! * n).

  • Postcondition: result.len() >= 0
fn str_permutations_n(s: Str, n: Int) -> Vec[Str]

All n-length arrangements of the characters of s (P(|s|, n) results, ordered, without repetition). n == 0 yields [""]; n < 0 or n > |s| yields an empty vector. Params: s the source string; n the arrangement length. Returns: a Vec[Str] of n-length permutations. Error case: n < 0 or n > |s| => empty vector; large inputs are guarded as in str_permutations. Complexity: O(P(n, k) * k).

  • Postcondition: result.len() >= 0
fn str_combinations(s: Str, n: Int) -> Vec[Str]

All n-length combinations of the characters of s, each kept in source order (C(|s|, n) results). n < 1 or n > |s| yields an empty vector, matching xiom.string.combine.str_combinations. Params: s the source string; n the combination length. Returns: a Vec[Str] of n-length combinations. Error case: n < 1 or n > |s| => empty vector. Complexity: O(C(n, k) * k).

  • Postcondition: result.len() >= 0
fn str_cartesian(a: Str, b: Str) -> Vec[Str]

Every character of a paired with every character of b, in order ("ab" x "12" yields "a1", "a2", "b1", "b2"). Params: a, b the source strings. Returns: a Vec[Str] of two-character pairs. Error case: none; an empty operand yields an empty vector. Complexity: O(|a| * |b|).

  • Postcondition: result.len() >= 0
fn str_interleave(a: Str, b: Str) -> Str

Merge a and b alternating characters, appending the remainder of the longer string ("abc" + "12" yields "a1b2c"). Params: a, b the strings to interleave. Returns: the interleaved string. Error case: none. Complexity: O(|a| + |b|).

  • Postcondition: result.len() == a.len() + b.len()
fn str_chunk(s: Str, n: Int) -> Vec[Str]

Split s into consecutive chunks of n bytes; the final chunk may be shorter. A chunk size below 1 or an empty input yields an empty vector. Params: s the source string; n the chunk size in bytes. Returns: a Vec[Str] of chunks covering s exactly once. Error case: n < 1 or s.len() == 0 => empty vector. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()
fn str_chunks_reverse(s: Str, n: Int) -> Vec[Str]

Split s into chunks of n bytes starting from the end; the remainder (if any) forms the first chunk. A chunk size below 1 or an empty input yields an empty vector. Params: s the source string; n the chunk size in bytes. Returns: a Vec[Str] of chunks in source order (first may be shorter). Error case: n < 1 or s.len() == 0 => empty vector. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()
fn str_windows(s: Str, n: Int) -> Vec[Str]

All length-n overlapping substrings (windows) of s. A window size below 1 or larger than the input yields an empty vector. Params: s the source string; n the window size in bytes. Returns: a Vec[Str] with one element per start position 0..len-n. Error case: n < 1 or len < n => empty vector. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()
fn str_chunk_bytes(s: Str, n: Int) -> Vec[Str]

Split s into chunks of n bytes that never split a multi-byte UTF-8 character: a chunk is extended to the end of a character that would cross the n-byte boundary. Params: s the source string; n the target chunk size in bytes. Returns: a Vec[Str] of chunks covering s exactly once. Error case: n < 1 or s.len() == 0 => empty vector. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()
fn str_reverse_words(s: Str) -> Str

Reverse the order of the whitespace-separated words of s, preserving the whitespace runs: only the token order changes ("a b" -> "b a"). Returns s unchanged when s has no words. Params: s the string whose words to reverse. Returns: the word-reversed string. Error case: none. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_unique_chars(s: Str) -> Str

The characters of s without duplicates, in first-seen order. Dedup is byte-based, so two different multi-byte code points sharing a leading byte are treated as duplicates (documented; ASCII is exact). Params: s the source string. Returns: a string of distinct characters. Error case: none. Complexity: O(|s|^2).

  • Postcondition: result.len() <= s.len()
fn str_frequencies(s: Str) -> Vec[(Char, Int)]

Each distinct character of s and its occurrence count, in first-seen order. Characters are derived from their bytes (ASCII-exact; multi-byte code points are counted per byte, documented). Params: s the source string. Returns: a Vec[(Char, Int)] of (character, count) pairs. Error case: none. Complexity: O(|s|^2).

  • Postcondition: result.len() <= s.len()
fn str_most_frequent(s: Str) -> Option[Char]

The character that appears most often in s, or None when s is empty. When several characters tie, the first-seen one wins. Params: s the source string. Returns: Some with the most frequent character, None when empty. Error case: none. Complexity: O(|s|^2).

  • Postcondition: result is Some(_) => s.len() > 0
fn str_char_set(s: Str) -> Vec[Char]

The distinct characters of s in first-seen order, as Char values. Params: s the source string. Returns: a Vec[Char] of distinct characters. Error case: none. Complexity: O(|s|^2).

  • Postcondition: result.len() <= s.len()



combine.xi

fn str_combinations(s: Str, n: Int) -> Vec[Str]

Returns all n-length combinations of the characters of s, in source order: within every combination the characters keep their relative order. A combination size below 1 or above the string length yields an empty vector. Params: s the source string; n the number of characters per combination. Returns: a Vec[Str] with C(|s|, n) elements. Error case: n < 1 or n > s.len() => empty vector. Complexity: O(C(|s|, n) * n).

fn str_combination_at(s: Str, n: Int, rank: Int) -> Str

Returns the n-length combination of the characters of s at the given rank (0-based, same enumeration order as str_combinations), or the empty string when rank is out of range. Params: s the source string; n the combination size; rank the 0-based combination index. Returns: the ranked combination string. Error case: "" when n < 1, n > s.len(), rank < 0, or rank >= C(|s|, n). Complexity: O(n^2) with O(1) binomial lookups.




compare.xi

fn str_compare(a: Str, b: Str) -> Int

Lexicographic byte-wise comparison of a and b. Returns a negative Int when a sorts before b, 0 when equal, and a positive Int when a sorts after b. Comparison is byte-by-byte over the UTF-8 representation, so the ordering matches Unicode code-point order only for ASCII inputs; multi-byte sequences compare by their raw bytes. Params: a, b the strings to compare. Returns: negative/zero/positive. Error case: none. Complexity: O(min(|a|, |b|)).

  • Postcondition: result >= -1 && result <= 1
fn str_compare_ignore_case(a: Str, b: Str) -> Int

Case-insensitive lexicographic comparison of a and b. ASCII uppercase letters are folded to lowercase before each byte comparison; all other bytes compare unchanged. The sign of the result follows str_compare: negative when a < b, zero when equal, positive when a > b. Params: a, b the strings to compare. Returns: negative/zero/positive. Error case: none. Complexity: O(min(|a|, |b|)).

  • Postcondition: result >= -1 && result <= 1
fn str_compare_natural(a: Str, b: Str) -> Int

Natural-order comparison of a and b: runs of ASCII digits are compared by their numeric value, so "x2" sorts before "x10". Between digit runs the comparison is byte-wise lexicographic, and equal-length numeric runs break ties by leading-zero count (fewer zeros sorts first). Params: a, b the strings to compare. Returns: negative/zero/positive. Error case: none. Complexity: O(|a| + |b|).

  • Postcondition: result >= -1 && result <= 1
fn str_eq_ignore_case(a: Str, b: Str) -> Bool

Returns true when a equals b ignoring ASCII letter case. Params: a, b the strings to compare. Returns: true when they compare equal under str_compare_ignore_case. Error case: none. Complexity: O(min(|a|, |b|)).




compat.xi

fn unicode_compatibility_normalize(s: Str) -> Str

Compatibility-normalize s to NFKC. Delegates to the canonical NFKC engine; see xiom.string.normalize.unicode_normalize_nfkc for the documented coverage (fullwidth forms, ligatures, fractions, circled numbers, ...). Params: s the string to normalize. Returns: the NFKC-normalized string. Error case: none; malformed UTF-8 bytes pass through approximately. Complexity: O(|s|).

fn unicode_decompose(s: Str) -> Vec[Str]

The canonical decomposition of each code point of s, one element per input code point in source order. Code points that decompose into a base letter plus a combining mark (the Latin-1 Supplement accented letters, see the local table) yield that pair concatenated as a single string; all other code points yield themselves. Params: s the string to decompose. Returns: a Vec[Str] with one element per code point of s. Error case: none; malformed UTF-8 bytes pass through as single bytes. Complexity: O(|s|).




cosine.xi

fn cosine_similarity(a: Str, b: Str, n: Int) -> Float64

Cosine of the angle between the length-n n-gram frequency vectors of a and b. Identical strings score 1.0; strings with no shared n-gram score 0.0. N-gram identity is by djb2 hash code (see the module header). Params: a, b - the strings to compare; n - the n-gram size (>= 1). Returns: the cosine similarity in 0.0..1.0; 0.0 when n < 1, when either input is shorter than n, or when either vector is empty. Errors: none (empty/short inputs are handled in the body). Complexity: O(|a| * |b|) worst case.

  • Precondition: true



damerau.xi

fn damerau_levenshtein_distance(a: Str, b: Str) -> Int

Damerau-Levenshtein distance between a and b: the minimum number of insertions, deletions, substitutions and adjacent-character transpositions needed to turn a into b. Delegates to xiom.misc.damerau_levenshtein_distance. Params: a, b - the strings to compare (raw byte sequences). Returns: the edit distance (>= 0). Errors: none. Complexity: O(|a| * |b|) time, O(|b|) space.

  • Postcondition: result >= 0
fn osa_distance(a: Str, b: Str) -> Int

Optimal string alignment (OSA) distance between a and b: an edit distance in which each adjacent-character transposition counts once and no substring may be edited more than once. Delegates to xiom.text.similarity.damerau_levenshtein. Params: a, b - the strings to compare (raw byte sequences). Returns: the OSA distance (>= 0). Errors: none. Complexity: O(|a| * |b|) time, O(|b|) space.

  • Postcondition: result >= 0



ea_width.xi

fn unicode_ea_width(c: Char) -> Int

East Asian display width of c: 0 (control/combining/zero-width), 1 (narrow, neutral, ambiguous), or 2 (wide/fullwidth). Ambiguous characters count 1 per the module contract. Unassigned codepoints fall back to 1. Params: c the character to measure. Returns: 0, 1 or 2 display cells. Error case: none. Complexity: O(1).

  • Postcondition: result >= 0
fn unicode_display_width(s: Str) -> Int

Display width of s, summing the per-character East Asian widths. This is the width the string would occupy in a monospaced terminal or table cell. Params: s the string to measure. Returns: total display width in cells (>= 0). Error case: none; malformed UTF-8 bytes are counted as width 1. Complexity: O(|s|).

  • Postcondition: result >= 0
fn unicode_truncate_display(s: Str, max_width: Int) -> Str

Truncate s so its display width does not exceed max_width cells. Characters are never split: the result ends on a character boundary, and a wide character that would overflow the limit is dropped entirely. Params: s the string to truncate; max_width the maximum display width. Returns: the longest prefix of s whose display width is <= max_width. Error case: max_width <= 0 yields ""; malformed bytes pass through whole. Complexity: O(|s|).




editdistance.xi

fn edit_distance(a: Str, b: Str) -> Int

Minimum number of edits (insertions, deletions, substitutions) needed to turn a into b (the Levenshtein distance). Delegates to xiom.text.similarity.levenshtein. Params: a, b - the strings to compare (raw byte sequences). Returns: the edit distance (>= 0). Errors: none. Complexity: O(|a| * |b|) time, O(|b|) space.

  • Postcondition: result >= 0
fn edit_distance_limited(a: Str, b: Str, max: Int) -> Int

Edit distance capped at max: the exact distance when it does not exceed max, otherwise max itself. The dynamic program only evaluates cells within max of the diagonal (|i - j| <= max), so the result is correct whenever it lies at or below max. A negative max is treated as unbounded and returns the exact distance. Params: a, b - the strings to compare; max - the cap (>= 0). Returns: min(edit_distance(a, b), max); the exact distance when max < 0. Errors: none (every input combination is handled in the body). Complexity: O(|a| * |b|) time worst case, O(|b|) space; the DP arithmetic runs only within the band |i - j| <= max.

  • Postcondition: result >= 0



emoji.xi

fn unicode_is_emoji(c: Char) -> Bool

True when c is an emoji character or emoji component codepoint: an emoji block, a skin-tone modifier (U+1F3FB..U+1F3FF), the emoji presentation selector (U+FE0F), ZWJ (U+200D) or the combining enclosing keycap (U+20E3). See the header for the documented coverage. Params: c the character to test. Returns: true when c is emoji or an emoji component. Error case: none. Complexity: O(1).

fn unicode_count_emoji(s: Str) -> Int

Number of emoji characters and components in s (bases plus modifiers, selectors, joiners). Full ZWJ sequences count each component separately. Params: s the string to scan. Returns: the count of emoji codepoints (>= 0). Error case: none; malformed UTF-8 bytes are skipped. Complexity: O(|s|).

  • Postcondition: result >= 0
fn unicode_has_emoji(s: Str) -> Bool

True when s contains at least one emoji character or component. Params: s the string to scan. Returns: true when s contains an emoji. Error case: none. Complexity: O(|s|).




escape.xi

fn str_escape(s: Str) -> Str

Escapes the control and special characters of s (\n, \t, \", \, \r) so the result can be embedded safely in source or data. All other characters pass through unchanged. Params: s the source string. Returns: the escaped string. Error case: none. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn str_unescape(s: Str) -> Str

Interprets the escape sequences in s (\n, \t, \", \, \r) back into literal characters. Unrecognised escapes are left unchanged, so str_escape then str_unescape is a faithful round-trip. Params: s the source string. Returns: the unescaped string. Error case: none. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn str_escape_ascii(s: Str) -> Str

Escapes every non-ASCII byte of s as a lowercase \xNN sequence; ASCII bytes pass through unchanged. Useful for producing pure-ASCII output. Params: s the source string. Returns: the ASCII-escaped string. Error case: none. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn str_escape_unicode(s: Str) -> Str

Escapes every non-ASCII code point of s as a lowercase \uNNNN sequence (four hex digits, high bits dropped for code points above U+FFFF); ASCII code points pass through unchanged. Useful for producing pure-ASCII output. Params: s the source string. Returns: the Unicode-escaped string. Error case: none. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0



fold.xi

fn unicode_casefold(s: Str) -> Str

Full Unicode case folding of s for case-insensitive matching. ASCII, Latin-1, Latin Extended-A, Greek and Cyrillic uppercase letters fold to their lowercase forms; the sharp s (ss/SS) folds to "ss" and dotted capital I (I) folds to "i" + combining dot. See xiom.string.casefold.str_casefold for the documented coverage. Params: s the string to fold. Returns: the case-folded string. Error case: none; malformed UTF-8 bytes pass through unchanged. Complexity: O(|s|).

fn unicode_fold_full(s: Str) -> Str

Full (F) Unicode case fold of s, applying the multi-character mappings (ss/SS -> "ss", I -> "i" + combining dot). Currently identical to unicode_casefold; both expose the same full case-folding table. Params: s the string to fold. Returns: the fully case-folded string. Error case: none; malformed UTF-8 bytes pass through unchanged. Complexity: O(|s|).




format.xi

fn str_format1[T](spec: Str, a: T) -> Result[Str, Str]

Format a single argument a against the spec template. The first "{}" in spec is replaced by the value's display string; values without a placeholder leave spec unchanged. Params: spec the template containing a "{}" placeholder; a the value. Returns: Ok with the formatted string; Err is never produced for this entry point (reserved for API symmetry). Error case: none. Complexity: O(|spec| + |value display|).

fn str_format2[T, U](spec: Str, a: T, b: U) -> Result[Str, Str]

Format two arguments a and b against the spec template; the first "{}" takes a, the second takes b. Params: spec the template; a, b the values. Returns: Ok with the formatted string. Error case: none. Complexity: O(|spec| + |display|).

fn str_format3[T, U, V](spec: Str, a: T, b: U, c: V) -> Result[Str, Str]

Format three arguments a, b and c against the spec template. Params: spec the template; a, b, c the values. Returns: Ok with the formatted string. Error case: none. Complexity: O(|spec| + |display|).




glob.xi

fn glob_match(pattern: Str, s: Str) -> Bool

Match s against the glob pattern, case-sensitive. Params: pattern the glob pattern; s the string to test. Returns: true when s matches pattern. Error case: none. Complexity: O(|pattern| * |s|) worst case.

fn glob_match_case_insensitive(pattern: Str, s: Str) -> Bool

Match s against the glob pattern, ignoring ASCII letter case. Bytes above 0x7F match byte-exactly. Params: pattern the glob pattern; s the string to test. Returns: true when s matches pattern case-insensitively. Error case: none. Complexity: O(|pattern| * |s|) worst case.




hamming.xi

fn hamming_distance(a: Str, b: Str) -> Int

Hamming distance between a and b: the number of byte positions where the two strings differ. Delegates to xiom.misc.hamming_distance. Params: a, b - the strings to compare (raw byte sequences). Returns: the number of differing positions; -1 when a.len() != b.len(). Error case: a length mismatch is reported via the -1 return (no trap). Complexity: O(|a|).

  • Postcondition: a.len() == b.len() => result >= 0



indent.xi

fn str_indent(s: Str, n: Int) -> Str

Prepends n spaces to each line of s. An indent level at or below 0 leaves s unchanged; empty lines are indented too. Params: s the source string; n the number of spaces per line. Returns: the indented string. Error case: none; n <= 0 is a no-op. Complexity: O(|s| * n).

fn str_indent_with(s: Str, n: Int, prefix: Str) -> Str

Prepends prefix repeated n times to each line of s. An indent level at or below 0 leaves s unchanged; empty lines are indented too. Params: s the source string; n the repeat count; prefix the indentation unit. Returns: the indented string. Error case: none; n <= 0 is a no-op. Complexity: O(|s| * n * |prefix|).

fn str_dedent(s: Str) -> Str

Removes the common leading whitespace (spaces and tabs) from all lines of s. Lines that are empty are ignored when computing the common width; a string with no common indentation is returned unchanged. Params: s the source string. Returns: the dedented string. Error case: none. Complexity: O(|s|).

  • Precondition: true
fn str_unindent(s: Str) -> Str

Removes one level of indentation from each line of s: a leading tab, or otherwise up to 4 leading spaces (fewer if the line has fewer). Lines with no leading whitespace are left unchanged. Params: s the source string. Returns: the unindented string. Error case: none. Complexity: O(|s|).




interleave.xi

fn str_interleave(a: Str, b: Str) -> Str

Merges a and b by alternating their characters: the characters of a and b are taken one at a time in turn; once the shorter string is exhausted the remainder of the longer string is appended. Params: a, b the strings to merge. Returns: the interleaved string. Error case: none. Complexity: O(|a| + |b|).

  • Precondition: true
fn str_interleave_n(parts: &Vec[Str], sep: Str) -> Str

Merges the parts character by character in a round-robin fashion: the first character of every part, then the second of every part, and so on. sep is inserted between adjacent output characters (not before the first and not after the last). An empty parts list yields the empty string. Params: parts the strings to merge; sep the separator between characters. Returns: the interleaved string with separators. Error case: parts.len() == 0 => "". Complexity: O(total chars * parts.len()).

  • Precondition: true



jaccard.xi

fn jaccard_similarity(a: Str, b: Str, n: Int) -> Float64

Jaccard index of the length-n n-gram sets of a and b: |A & B| / |A | B|, where each set holds the distinct character n-grams of one input. Delegates to xiom.text.similarity.jaccard_similarity. Params: a, b - the strings to compare; n - the n-gram size (>= 1). Returns: the Jaccard similarity in 0.0..1.0; 1.0 when both inputs produce identical n-gram sets; 0.0 when n < 1, when an input is shorter than n, or when both inputs have no n-grams. Errors: none (empty/short inputs are handled in the body). Complexity: O(|a| * |b|) worst case.




jaro.xi

fn jaro_similarity(a: Str, b: Str) -> Float64

Jaro similarity of a and b in the 0.0..1.0 range (1.0 = identical, 0.0 = no matching characters). Delegates to xiom.misc.jaro_similarity. Params: a, b - the strings to compare (raw byte sequences). Returns: the Jaro score; 1.0 when both inputs are empty, 0.0 when either input is empty or no characters match. Errors: none (empty inputs are handled in the body). Complexity: O(|a| * |b|) worst case.

fn jaro_winkler_similarity(a: Str, b: Str) -> Float64

Jaro-Winkler similarity of a and b: the Jaro score boosted by a common-prefix bonus (up to 4 prefix characters, scale 0.1). Delegates to xiom.misc.jaro_winkler_similarity. Params: a, b - the strings to compare (raw byte sequences). Returns: the Jaro-Winkler score in 0.0..1.0. Errors: none. Complexity: O(|a| * |b|) worst case.




join.xi

fn str_join(parts: &Vec[Str], sep: Str) -> Str

Joins parts with sep between consecutive elements. Returns an empty string when parts is empty. Complexity: O(total bytes of parts).

  • Postcondition: parts.len() == 0 => result.len() == 0
fn str_join_after(parts: &Vec[Str], sep: Str, after: Int) -> Str

Joins parts, inserting sep after every after-th element. When after <= 0, no separator is inserted at all. Returns an empty string when parts is empty. Complexity: O(total bytes of parts).

  • Postcondition: after <= 0 => result.len() == 0
fn vec_int_join(values: &Vec[Int], sep: Str) -> Str

Joins the Int values in values with sep between consecutive elements. Returns an empty string when values is empty. Complexity: O(total digits of values).

  • Postcondition: values.len() == 0 => result.len() == 0
fn vec_float_join(values: &Vec[Float64], sep: Str) -> Str

Joins the Float64 values in values with sep between consecutive elements. Returns an empty string when values is empty. Complexity: O(total digits of values).

  • Postcondition: values.len() == 0 => result.len() == 0



lcp.xi

fn longest_common_prefix(a: Str, b: Str) -> Int

Length of the longest common prefix of a and b (in bytes). Delegates to xiom.text.similarity.longest_common_prefix. Params: a, b - the strings to compare. Returns: the shared prefix length in 0..min(|a|, |b|). Errors: none. Complexity: O(min(|a|, |b|)).

  • Postcondition: result >= 0
fn lcp_of_many(strings: &Vec[Str]) -> Int

Length of the longest common prefix shared by every string in strings (in bytes). The empty vector has a common prefix of length 0; a single-element vector shares its entire length. Params: strings - the strings to compare. Returns: the shared prefix length (>= 0). Errors: none (the empty vector is handled in the body). Complexity: O(total bytes of all strings).

  • Postcondition: result >= 0



lcs.xi

fn longest_common_subsequence(a: Str, b: Str) -> Int

Length of the longest common subsequence of a and b (a subsequence keeps the relative order of characters without requiring contiguity). Delegates to xiom.text.similarity.longest_common_subsequence. Params: a, b - the strings to compare. Returns: the LCS length (>= 0); e.g. 3 for ("ABCDGH", "AEDFHR") whose longest common subsequence is "ADH". Errors: none. Complexity: O(|a| * |b|) time, O(|b|) space.

  • Postcondition: result >= 0
fn longest_common_substring(a: Str, b: Str) -> Int

Length of the longest common contiguous substring of a and b. Delegates to xiom.text.similarity.longest_common_substring. Params: a, b - the strings to compare. Returns: the substring length (>= 0); e.g. 3 for ("abcdef", "zcdemf") whose longest common substring is "cde". Errors: none. Complexity: O(|a| * |b|) time, O(|b|) space.

  • Postcondition: result >= 0



lcsuffix.xi

fn longest_common_suffix(a: Str, b: Str) -> Int

Length of the longest common suffix of a and b (in bytes). Delegates to xiom.text.similarity.longest_common_suffix. Params: a, b - the strings to compare. Returns: the shared suffix length in 0..min(|a|, |b|). Errors: none. Complexity: O(min(|a|, |b|)).

  • Postcondition: result >= 0



levenshtein.xi

fn levenshtein_distance(a: Str, b: Str) -> Int

Levenshtein edit distance between a and b: the minimum number of insertions, deletions and substitutions needed to turn a into b. Delegates to xiom.misc.levenshtein_distance. Params: a, b - the strings to compare (raw byte sequences). Returns: the edit distance (>= 0). Errors: none. Complexity: O(|a| * |b|) time, O(min(|a|,|b|)) space.

  • Postcondition: result >= 0
fn levenshtein_normalized(a: Str, b: Str) -> Float64

Levenshtein distance normalized to the 0.0..1.0 range, defined as distance / max(|a|, |b|): 0.0 for identical strings, 1.0 when one of the inputs is empty, and strictly between 0.0 and 1.0 otherwise. Params: a, b - the strings to compare. Returns: the normalized distance in 0.0..1.0 (inclusive). Errors: none (the empty-vs-empty case is guarded to avoid a division by zero). Complexity: O(|a| * |b|) via the underlying distance.




linebreak.xi

fn unicode_line_break_points(s: Str) -> Vec[Int]

Byte offsets in s where a line break is allowed, in increasing order. The offsets are boundaries: the text up to an offset ends one line and the text from that offset starts the next. Mandatory breaks (newline, paragraph separator) are reported just after the break character, so the character stays with the preceding line. See the module header for the covered rules. Params: s the string to analyse. Returns: the list of allowed break byte offsets (may be empty). Error case: none; malformed UTF-8 bytes are skipped without break points. Complexity: O(|s|).

fn unicode_split_lines(s: Str) -> Vec[Str]

Split s into lines at the allowed break points. The line break character of a mandatory break stays with the preceding line; space runs also stay with the preceding line. A trailing break produces a trailing empty line. Params: s the string to split. Returns: the list of line substrings. Error case: none. Complexity: O(|s| + number of break points).




lowercase.xi

fn str_lowercase(s: Str) -> Str

Converts all characters of s to lowercase. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn char_lowercase(c: Char) -> Char

Returns the lowercase variant of c, or c unchanged when c has no lowercase mapping. Complexity: O(1).




metaphone.xi

fn metaphone(s: Str) -> Str

Metaphone code of s. Uppercases the input, keeps the first letter (with a few start-of-word rules such as leading "kn" and "wr"), drops vowels, maps the remaining consonants, then removes consecutive duplicate codes and any non-leading H/W. Empty input encodes to "". Params: s the word to encode. Returns: the Metaphone code ("" for empty input). Error case: none. Complexity: O(|s|).

fn metaphone_compare(a: Str, b: Str) -> Bool

True when a and b share the same Metaphone code, i.e. they sound alike. Two empty strings compare equal (both encode to ""). Params: a, b the strings to compare. Returns: true when metaphone(a) == metaphone(b). Error case: none. Complexity: O(|a| + |b|).




mirror.xi

fn unicode_mirror_char(c: Char) -> Char

Return the mirror image of c per the Unicode Bidi_Mirrored property for the covered pairs: parentheses, square brackets, curly braces, angle brackets, slash pairs, guillemets and single-angle quotes. Characters without a mirror mapping are returned unchanged. Params: c the character to mirror. Returns: the mirrored character, or c itself. Error case: none. Complexity: O(1).

fn unicode_is_mirrored(c: Char) -> Bool

Return true when c has the Unicode Bidi_Mirrored property for the covered pairs listed in unicode_mirror_char. Params: c the character to test. Returns: true when c has a mirror image, false otherwise. Error case: none. Complexity: O(1).




nfkc.xi

fn unicode_normalize_nfkc(s: Str) -> Str

Normalize s to NFKC (compatibility composition). See xiom.string.normalize.unicode_normalize_nfkc for the documented coverage. Params: s the string to normalize. Returns: the NFKC-normalized string. Error case: none; malformed UTF-8 bytes pass through approximately. Complexity: O(|s|).

fn unicode_normalize_nfkd(s: Str) -> Str

Normalize s to NFKD (compatibility decomposition). See xiom.string.normalize.unicode_normalize_nfkd for the documented coverage. Params: s the string to normalize. Returns: the NFKD-normalized string. Error case: none; malformed UTF-8 bytes pass through approximately. Complexity: O(|s|).




ngram.xi

fn ngram_extract(s: Str, n: Int) -> Vec[Str]

All contiguous length-n character n-grams of s (n = 1 -> single characters), in order of appearance, duplicates included. Delegates to xiom.text.similarity.ngram_extract. Params: s - the source string; n - the n-gram size (>= 1). Returns: the list of n-grams; empty when n < 1 or when s is shorter than n. A source of length exactly n yields the single n-gram s. Errors: none (short/empty inputs yield an empty list). Complexity: O(|s|) time with O(|s|) output.

fn ngram_count(s: Str, n: Int) -> Int

Number of contiguous length-n character n-grams of s, i.e. max(0, |s| - n + 1) for n >= 1. Params: s - the source string; n - the n-gram size (>= 1). Returns: the n-gram count; 0 when n < 1 or when s is shorter than n. Errors: none. Complexity: O(1).

  • Postcondition: result >= 0



ngram_similarity.xi

fn ngram_similarity(a: Str, b: Str, n: Int) -> Float64

Similarity of a and b from their shared length-n n-grams, computed as the Jaccard index over the distinct n-gram hash-code sets (see xiom.text.similarity). Delegates to xiom.text.similarity.ngram_similarity. Params: a, b - the strings to compare; n - the n-gram size (>= 1). Returns: the similarity in 0.0..1.0; 1.0 for identical strings; 0.0 when n < 1, when an input is shorter than n, or when either side has no n-grams. Errors: none (empty/short inputs are handled in the body). Complexity: O(|a| * |b|) worst case.




normalize.xi

fn unicode_normalize_nfc(s: Str) -> Str

Normalize s to NFC (canonical composition): characters are canonically decomposed, canonically reordered, then recomposed to their precomposed forms where one exists (e.g. "e\u0301" -> "e"). Characters outside the covered table pass through unchanged. Params: s the string to normalize. Returns: the NFC-normalized string. Error case: none; malformed UTF-8 bytes pass through approximately. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn unicode_normalize_nfd(s: Str) -> Str

Normalize s to NFD (canonical decomposition): precomposed characters are decomposed into their base letter plus combining marks, and combining marks are canonically reordered by combining class (e.g. "e" -> "e" + U+0301). Params: s the string to normalize. Returns: the NFD-normalized string. Error case: none; malformed UTF-8 bytes pass through approximately. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn unicode_normalize_nfkc(s: Str) -> Str

Normalize s to NFKC (compatibility composition): NFKD then NFC-style recomposition. Compatibility characters such as ligatures, superscripts and fullwidth forms are decomposed first (e.g. "1" -> "1", "[U+FF66]" -> "[U+FF66]"... 1:1 fullwidth forms fold to ASCII). See the module header for the covered set. Params: s the string to normalize. Returns: the NFKC-normalized string. Error case: none; malformed UTF-8 bytes pass through approximately. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn unicode_normalize_nfkd(s: Str) -> Str

Normalize s to NFKD (compatibility decomposition): like NFD plus the compatibility mappings (e.g. "fi" -> "fi", "1/2" -> "1/2", "8" -> "8"). Params: s the string to normalize. Returns: the NFKD-normalized string. Error case: none; malformed UTF-8 bytes pass through approximately. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0
fn str_normalize_ascii(s: Str) -> Str

Fold s to plain ASCII, removing accents and combining marks. Accented Latin letters reduce to their base letter ("cafe" -> "cafe"); common non-ASCII letters without an ASCII base are transliterated via a small map ("o" -> "o", "ss" -> "s", "ae" -> "a"). Characters with no ASCII transliteration are dropped. See the module header for the covered set. Params: s the string to fold. Returns: an ASCII-only string. Error case: none; malformed UTF-8 bytes pass through approximately. Complexity: O(|s|).

  • Postcondition: s.len() == 0 => result.len() == 0



pad.xi

fn str_pad_left(s: Str, width: Int, pad: Char) -> Str

Pads s on the left with pad up to width bytes. Returns s unchanged when s is already at least width bytes long. Complexity: O(width - |s|).

  • Postcondition: width <= s.len() => result == s
fn str_pad_right(s: Str, width: Int, pad: Char) -> Str

Pads s on the right with pad up to width bytes. Returns s unchanged when s is already at least width bytes long. Complexity: O(width - |s|).

  • Postcondition: width <= s.len() => result == s
fn str_pad_both(s: Str, width: Int, pad: Char) -> Str

Pads s on both sides with pad up to width bytes, distributing the padding so that the left side carries the extra character when the pad count is odd. Returns s unchanged when s is already at least width bytes long. Complexity: O(width - |s|).

  • Postcondition: width <= s.len() => result == s
fn str_center(s: Str, width: Int, pad: Char) -> Str

Centers s in a field of width bytes using pad. Equivalent to str_pad_both. Returns s unchanged when s is already at least width bytes long. Complexity: O(width - |s|).

  • Postcondition: width <= s.len() => result == s
fn str_pad_start(s: Str, width: Int, pad: Char) -> Str

Alias of str_pad_left: pads s at the start with pad up to width. Complexity: O(width - |s|).

  • Postcondition: width <= s.len() => result == s
fn str_pad_end(s: Str, width: Int, pad: Char) -> Str

Alias of str_pad_right: pads s at the end with pad up to width. Complexity: O(width - |s|).

  • Postcondition: width <= s.len() => result == s



permute.xi

fn str_permutations(s: Str) -> Vec[Str]

All permutations of the characters of s, treating the characters as distinct (n! results). An empty string yields a vector containing "". The permutations are emitted in lexicographic byte order. Params: s the source string. Returns: a Vec[Str] with n! permutations. Error case: inputs longer than 8 characters return an empty vector (documented guard against an impractical result set). Complexity: O(n! * n).

fn str_permutations_n(s: Str, n: Int) -> Vec[Str]

All n-length arrangements of the characters of s (P(|s|, n) results). n == 0 yields [""]; n < 0 or n > |s| yields an empty vector. Params: s the source string; n the arrangement length. Returns: a Vec[Str] of n-length permutations. Error case: n < 0 or n > |s| => empty vector; large inputs are guarded as in str_permutations. Complexity: O(P(n, k) * k).

fn str_permutation_at(s: Str, rank: Int) -> Str

The permutation of the (distinct) characters of s at rank in lexicographic order, or "" when rank is out of range. For "abc": rank 0 is "abc", 1 is "acb", 2 is "bac", and so on up to rank 5 = "cba". Params: s the source string; rank the 0-based permutation index. Returns: the ranked permutation, "" when rank is out of range. Error case: rank < 0 or rank >= |s|! => ""; inputs longer than 20 characters => "" (factorial range guard). Complexity: O(|s|^2).




printf.xi

fn str_printf_i1(spec: Str, a: Int) -> Result[Str, Str]

Format the Int a per the printf spec. Supports the integer conversions %d/%i/%u/%x/%X/%o/%b with flags, width and precision. Wrong conversion family or missing values yield Err. Params: spec the printf format; a the integer value. Returns: Ok with the formatted string, Err on a malformed or mismatched spec. Error case: malformed spec, non-integer conversion, missing arguments. Complexity: O(|spec| + digits).

fn str_printf_f1(spec: Str, a: Float64) -> Result[Str, Str]

Format the Float64 a per the printf spec. Supports %f/%F/%e/%E/%g/%G with flags, width and precision. Wrong conversion family or missing values yield Err. Params: spec the printf format; a the float value. Returns: Ok with the formatted string, Err on a malformed or mismatched spec. Error case: malformed spec, non-float conversion, missing arguments. Complexity: O(|spec| + |fraction digits|).

fn str_printf_s1(spec: Str, a: Str) -> Result[Str, Str]

Format the Str a per the printf spec. Supports %s with flags, width and precision. Wrong conversion family or missing values yield Err. Params: spec the printf format; a the string value. Returns: Ok with the formatted string, Err on a malformed or mismatched spec. Error case: malformed spec, non-string conversion, missing arguments. Complexity: O(|spec| + |a|).




repeat.xi

fn str_repeat(s: Str, n: Int) -> Str

Repeats s n times. Returns the empty string when n <= 0. Complexity: O(n * |s|).

fn str_repeat_char(c: Char, n: Int) -> Str

Returns a string consisting of c repeated n times. Returns the empty string when n <= 0. Multi-byte characters are encoded correctly. Complexity: O(n).




replace.xi

fn str_replace(s: Str, from: Str, to: Str) -> Str

Replaces all non-overlapping occurrences of from with to in s. Returns s unchanged when from is empty or does not occur. Complexity: O(|s| * |from|).

  • Postcondition: from.len() == 0 => result == s
fn str_replace_all(s: Str, from: Str, to: Str) -> Str

Replaces all non-overlapping occurrences of from with to in s. Returns s unchanged when from is empty or does not occur. Complexity: O(|s| * |from|).

  • Postcondition: from.len() == 0 => result == s
fn str_replace_n(s: Str, from: Str, to: Str, n: Int) -> Str

Replaces at most n non-overlapping occurrences of from with to in s. When n <= 0, returns s unchanged. Returns s unchanged when from is empty or does not occur. Complexity: O(|s| * |from|).

  • Postcondition: n <= 0 => result == s
fn str_replace_first(s: Str, from: Str, to: Str) -> Str

Replaces the first occurrence of from with to in s. Returns s unchanged when from is empty or does not occur. Complexity: O(|s| * |from|).

  • Postcondition: from.len() == 0 => result == s
fn str_replace_last(s: Str, from: Str, to: Str) -> Str

Replaces the last occurrence of from with to in s. Returns s unchanged when from is empty or does not occur. Complexity: O(|s| * |from|).

  • Postcondition: from.len() == 0 => result == s



reverse.xi

fn str_reverse(s: Str) -> Str

Reverses the characters of s, iterating over UTF-8 character boundaries so multi-byte characters are preserved. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_reverse_words(s: Str) -> Str

Reverses the order of the whitespace-separated words of s. The runs of whitespace between words are preserved as runs; only the token order is reversed. Returns s unchanged when s has no words. Complexity: O(|s|).

fn str_reverse_chars(s: Str) -> Str

Alias of str_reverse: reverses the characters of s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()



rotate.xi

fn str_rotate(s: Str, n: Int) -> Str

Rotate s right by n byte positions: a positive n moves characters toward the end of the string ("abcde" rotated right by 2 is "deabc"). A negative n rotates left. Rotating by a multiple of |s| returns s. Params: s the string to rotate; n the rotation amount in bytes. Returns: the rotated string. Error case: none; the empty string is returned unchanged. Complexity: O(|s|).

fn str_rotate_left(s: Str, n: Int) -> Str

Rotate s left by n byte positions ("abcde" rotated left by 2 is "cdeab"). A negative n rotates right. Params: s the string to rotate; n the rotation amount in bytes. Returns: the rotated string. Error case: none; the empty string is returned unchanged. Complexity: O(|s|).

fn str_rotate_right(s: Str, n: Int) -> Str

Rotate s right by n byte positions; identical to str_rotate and kept as the explicit right-rotation entry point. Params: s the string to rotate; n the rotation amount in bytes. Returns: the rotated string. Error case: none; the empty string is returned unchanged. Complexity: O(|s|).




scanf.xi

type FloatScan

Results of str_scanf_floats: the parsed Float64 values in v0..v7 (the first count slots are valid) and the unconsumed remainder of the input. On failure is_ok is false, count is 0, the value slots are 0.0 and remainder carries the error message.

LAYOUT NOTE (R44, 2026-09-18): this struct was formerly unified with xiom.fmt.FloatScan by the codegen same-name dedup, which hid a type mismatch in str_scanf_floats. The fmt twin is now FormatFloatScan and this wrapper copies every field explicitly, so the two leaves are genuinely independent (same field order/types, different leaf + names).

Field Type
is_ok Bool
count Int
v0 Float64
v1 Float64
v2 Float64
v3 Float64
v4 Float64
v5 Float64
v6 Float64
v7 Float64
remainder Str
fn str_scanf(s: Str, spec: Str) -> Result[Vec[Str], Str]

Scan s per spec, extracting the raw matched fields. Literal characters match exactly; spec whitespace skips input whitespace. Conversions: %d/%i/%u (decimal), %x/%X (hex, optional 0x), %f/%e/%g (float), %s (token), %c (exact chars), width caps, * suppresses. Returns the captured token strings in order, Err on any mismatch. Params: s the input string; spec the scanf-style format. Returns: Ok with the matched token strings, Err on mismatch. Error case: unterminated directive, no match, literal mismatch. Complexity: O(|s| + |spec|).

fn str_scanf_ints(s: Str, spec: Str) -> Result[Vec[Int], Str]

Scan s per spec, extracting Int values. The %d/%i/%u (decimal) and %x/%X (hex) tokens are converted with overflow checking; any other conversion in the spec yields Err. Params: s the input string; spec the scanf-style format. Returns: Ok with the parsed integers in token order, Err on mismatch or a non-integer conversion. Error case: parse failure, integer overflow, non-integer conversion. Complexity: O(|s| + |spec|).

fn str_scanf_floats(s: Str, spec: Str) -> FloatScan

Scan s per spec, extracting Float64 values (%f/%e/%g tokens). Values land in v0..v7 in token order with count valid slots. Specs with more than eight float conversions, or with a non-float conversion, yield is_ok = false with error set.

NOTE (R44): xiom.fmt.FloatScan was renamed FormatFloatScan; this wrapper copies the fields explicitly, so remainder is the fmt error slot on failure and the empty string on success. The unconsumed input tail is not populated; use str_scanf with a trailing capture to observe unconsumed input. Params: s the input string; spec the scanf-style format. Returns: a FloatScan struct. Error case: parse failure, too many float conversions, non-float conversion. Complexity: O(|s| + |spec|).




script.xi

fn unicode_script(c: Char) -> Str

ISO 15924 script code of c, e.g. "Latn" for 'A', "Hani" for a CJK ideograph, "Zyyy" for common punctuation and digits. Unmapped codepoints report "Zzzz" (unknown/unassigned). Params: c the character to classify. Returns: the four-letter ISO 15924 script code. Error case: none. Complexity: O(1).

fn unicode_script_name(code: Str) -> Str

Human-readable English script name for an ISO 15924 code, e.g. "Latn" -> "Latin", "Zyyy" -> "Common". Unknown or unrecognised codes yield "Unknown". Params: code the four-letter ISO 15924 code. Returns: the long script name. Error case: none; unknown codes map to "Unknown". Complexity: O(1).




search.xi

fn str_index_of(s: Str, needle: Str) -> Option[Int]

Returns the byte offset of the first occurrence of needle in s, or None when needle does not occur. An empty needle matches at offset 0. Params: s the haystack; needle the substring to find. Returns: Some(offset) on the first match, None when absent. Error case: none. Complexity: O(|s| * |needle|).

  • Postcondition: needle.len() == 0 => result.is_some
fn str_last_index_of(s: Str, needle: Str) -> Option[Int]

Returns the byte offset of the last occurrence of needle in s, or None when needle does not occur. An empty needle matches at the end of s (offset s.len()). Params: s the haystack; needle the substring to find. Returns: Some(offset) on the last match, None when absent. Error case: none. Complexity: O(|s| * |needle|).

  • Postcondition: needle.len() == 0 => result.is_some
fn str_contains(s: Str, needle: Str) -> Bool

Returns true when s contains needle at least once. Params: s the haystack; needle the substring to look for. Returns: true on a match, false otherwise (including an empty needle). Error case: none. Complexity: O(|s| * |needle|).

  • Postcondition: needle.len() == 0 => result == true
fn str_contains_any(s: Str, needles: &Vec[Str]) -> Bool

Returns true when s contains at least one of the needles. Params: s the haystack; needles the list of substrings to look for. Returns: true on the first needle found, false when none match. Error case: none. Complexity: O(k * |s| * max |needle|) where k = needles.len().

  • Postcondition: needles.len() == 0 => result == false
fn str_count_occurrences(s: Str, needle: Str) -> Int

Returns the number of non-overlapping occurrences of needle in s. An empty needle yields 0 (an occurrence requires at least one byte). Params: s the haystack; needle the substring to count. Returns: the occurrence count (>= 0). Error case: none. Complexity: O(|s| * |needle|).

  • Postcondition: result >= 0
fn str_find_any(s: Str, needles: &Vec[Str]) -> Option[Int]

Returns the byte offset of the earliest occurrence of any needle in s, or None when none of the needles occur. When several needles match at the same offset the first needle in needles wins. Empty needles match at offset 0. Params: s the haystack; needles the list of substrings to look for. Returns: Some(offset) of the earliest match, None when none match. Error case: none. Complexity: O(k * |s| * max |needle|) where k = needles.len().

  • Postcondition: needles.len() == 0 => result.is_some == false



segment.xi

fn unicode_grapheme_clusters(s: Str) -> Vec[Str]

Segment s into grapheme clusters, each returned as its own string. A cluster is a base character followed by its combining (Extend) marks; a CR followed by LF forms a single cluster. Characters outside the covered Extend set start their own cluster. Params: s the string to segment. Returns: a Vec[Str] whose concatenation equals s. Error case: none; malformed UTF-8 bytes pass through as single bytes. Complexity: O(|s|).

fn unicode_segment_graphemes(s: Str) -> Vec[Int]

Return the byte offsets of the grapheme cluster boundaries of s, including the start (0) and the end (|s|). Adjacent boundaries delimit the clusters reported by unicode_grapheme_clusters. Params: s the string to segment. Returns: a Vec[Int] with the first element 0 and the last element |s|. Error case: none; empty input yields [0]. Complexity: O(|s|).




sentencebreak.xi

fn unicode_sentence_boundaries(s: Str) -> Vec[Int]

Byte offsets in s where a new sentence begins (the start of every sentence after the first), in increasing order. A boundary follows the terminator run and its whitespace, so the whitespace stays with the previous sentence. See the module header for the covered rules. Params: s the string to analyse. Returns: the list of sentence-start byte offsets (may be empty). Error case: none; malformed UTF-8 bytes are skipped without boundaries. Complexity: O(|s|).

fn unicode_split_sentences(s: Str) -> Vec[Str]

Split s into sentences at the sentence boundaries. The terminator run and its trailing whitespace stay with the preceding sentence. Params: s the string to split. Returns: the list of sentence substrings. Error case: none. Complexity: O(|s| + number of boundaries).




shuffle.xi

fn str_shuffle(s: Str) -> Str

Random permutation of the characters of s via Fisher-Yates, drawing swap indices from the runtime PRNG. The result is a rearrangement of the characters of s; the order is not specified. Params: s the string to shuffle. Returns: a random permutation of the characters of s. Error case: none; the empty string maps to itself. Complexity: O(|s|).

fn str_shuffle_seeded(s: Str, seed: Int) -> Str

Deterministic shuffle of s using the given seed: the same seed always produces the same permutation via the Park-Miller sequence. Params: s the string to shuffle; seed the PRNG seed. Returns: the seeded permutation of s. Error case: none; the empty string maps to itself. Complexity: O(|s|).

fn str_shuffle_words(s: Str) -> Str

Random permutation of the whitespace-separated words of s, rejoined with single spaces (spacing runs are not preserved). Params: s the string whose words to shuffle. Returns: the shuffled words joined by single spaces. Error case: none; a string with no words yields "". Complexity: O(|s|).




slice.xi

fn str_slice(s: Str, start: Int, end: Int) -> Str

Returns the substring of s from byte index start (inclusive) to byte index end (exclusive), following the string.str_slice convention: a negative start is clamped to 0, end beyond the string length is clamped to the length, and an out-of-order range yields the empty string. Params: s the source string; start the inclusive start byte index; end the exclusive end byte index. Returns: the substring in [start, end). Error case: none - indices are clamped before use; never out-of-bounds. Complexity: O(end - start).

  • Postcondition: result.len() <= s.len()
fn str_substring(s: Str, start: Int, len: Int) -> Str

Returns len bytes of s starting at byte index start. Invalid ranges (negative start, negative len, or start at/after the end of s) are rejected with the empty string - never out-of-bounds. Params: s the source string; start the inclusive start byte index; len the number of bytes to take. Returns: the substring, or "" when the range is invalid. Error case: "" when start < 0, len < 0, or start >= s.len(). Complexity: O(len).

  • Postcondition: result.len() <= s.len()
fn str_chars(s: Str) -> Vec[Char]

Returns the characters of s as a vector, in source order. The runtime's char reader is byte-oriented, so each element carries the leading byte of the UTF-8 sequence it starts (for ASCII this equals the code point). Iteration advances at real UTF-8 boundaries, so one element is produced per Unicode character. Params: s the source string. Returns: a Vec[Char] with one element per Unicode character. Error case: none; empty input yields an empty vector. Complexity: O(s.len()).

  • Postcondition: result.len() <= s.len()
fn str_bytes(s: Str) -> Vec[UInt8]

Returns the raw bytes of s as a vector, in source order. Params: s the source string. Returns: a Vec[UInt8] with one element per byte of s. Error case: none; empty input yields an empty vector. Complexity: O(s.len()).

  • Postcondition: result.len() == s.len()
fn str_code_points(s: Str) -> Vec[Int]

Returns the Unicode code points of s as integers, in source order. Iterates at UTF-8 character boundaries via the runtime char reader. Params: s the source string. Returns: a Vec[Int] with one element per Unicode code point of s. Error case: none; empty input yields an empty vector. Complexity: O(s.len()).

  • Postcondition: result.len() <= s.len()



soundex.xi

fn soundex(s: Str) -> Str

Four-character American Soundex code of s. The first letter is kept uppercased, the remaining letters are mapped to digit codes with adjacent duplicates collapsed (unless separated by a vowel), and the code is padded or truncated to exactly 4 characters. Empty input encodes to "". Params: s the word to encode. Returns: the 4-character Soundex code ("" for empty input). Error case: none; non-alphabetic leading characters yield their code 0. Complexity: O(|s|).

fn soundex_compare(a: Str, b: Str) -> Bool

True when a and b share the same Soundex code, i.e. they sound alike. Two empty strings compare equal (both encode to ""). Params: a, b the strings to compare. Returns: true when soundex(a) == soundex(b). Error case: none. Complexity: O(|a| + |b|).




split.xi

fn str_split(s: Str, delim: Str) -> Vec[Str]

Splits s on every occurrence of delim. Always returns at least one part. Complexity: O(|s|).

  • Precondition: delim.len() > 0
  • Postcondition: result.len() >= 1
fn str_split_n(s: Str, delim: Str, n: Int) -> Vec[Str]

Splits s on delim into at most n parts. When n <= 1, returns a single part holding all of s. Always returns at least one part. Complexity: O(|s|).

  • Postcondition: result.len() >= 1
fn str_split_any(s: Str, delims: &Vec[Str]) -> Vec[Str]

Splits s on any of the delimiters in delims. The longest delimiter match at each position wins; when delims is empty, returns a single part holding all of s. Always returns at least one part. Complexity: O(|s| * |delims|).

  • Postcondition: result.len() >= 1
fn str_split_once(s: Str, delim: Str) -> (Str, Str)

Splits s at the first occurrence of delim into a pair holding the part before delim and the part after it. When delim does not occur in s, returns (s, ""). Complexity: O(|s|).

fn str_lines(s: Str) -> Vec[Str]

Splits s on newline boundaries; the lines exclude the trailing newline. Always returns at least one part. Complexity: O(|s|).

  • Postcondition: result.len() >= 1
fn str_words(s: Str) -> Vec[Str]

Splits s on whitespace boundaries into words. Returns an empty vector when s contains no words. Complexity: O(|s|).

fn str_rsplit(s: Str, delim: Str) -> Vec[Str]

Splits s on delim scanning from the end of s; the parts are returned in source order. When delim is empty or does not occur, returns a single part holding all of s. Complexity: O(|s|).

  • Postcondition: result.len() >= 1



string.xi

fn str_len(s: Str) -> Int

Byte length of the string.

  • Postcondition: result >= 0

fn str_concat(a: Str, b: Str) -> Str

Concatenation of two strings.

  • Postcondition: result.len() == a.len() + b.len()

fn str_slice(s: Str, start: Int, end: Int) -> Str

Byte slice [start, end) of the string.

  • Postcondition: end >= start && start >= 0 && end <= s.len() => result.len() == end - start
  • Postcondition: result.len() <= s.len()

fn str_contains(s: Str, substr: Str) -> Bool

True when substr occurs in the string.

  • Postcondition: substr.len() == 0 => result

fn str_starts_with(s: Str, prefix: Str) -> Bool

True when the string starts with prefix.

  • Postcondition: prefix.len() == 0 => result

fn str_ends_with(s: Str, suffix: Str) -> Bool

True when the string ends with suffix.

  • Postcondition: suffix.len() == 0 => result

fn str_split(s: Str, delimiter: Str) -> Vec[Str]

Split on delimiter into parts (empty parts preserved).

  • Postcondition: result.len() >= 1

fn str_trim(s: Str) -> Str

Copy without leading/trailing ASCII whitespace.

  • Postcondition: result.len() <= s.len()

fn str_to_int(s: Str) -> Result[Int, Str]

Parse an Int; Err with a message on bad input.

fn str_to_float(s: Str) -> Result[Float64, Str]

Parse a Float64; Err with a message on bad input.

fn str_upper(s: Str) -> Str

Copy with lowercase letters uppercased.

  • Postcondition: result.len() == s.len()

fn str_lower(s: Str) -> Str

Copy with uppercase letters lowercased.

  • Postcondition: result.len() == s.len()

fn format(fmt: Str) -> Str

Return fmt unchanged (formatting with no arguments).

fn format1(fmt: Str, arg: Str) -> Str

Substitute the first {} placeholder with arg.

  • Postcondition: result.len() >= fmt.len() - 2 + arg.len()

fn format2(fmt: Str, arg1: Str, arg2: Str) -> Str

Substitute the first two {} placeholders with the arguments.

fn byte_at(s: Str, pos: Int) -> UInt8

Byte value at pos, or 0 when out of bounds.

  • Precondition: true

fn char_at(s: Str, pos: Int) -> Option[Char]

UTF-8 character at byte position pos, or None.

  • Postcondition: result is Some(_) => pos >= 0 && pos < s.len()
  • Postcondition: result is None => pos < 0 || pos >= s.len()

fn index_of(s: Str, substr: Str) -> Option[Int]

Byte index of the first occurrence, or None.

  • Precondition: substr.len() > 0
  • Postcondition: result is Some(_) => result >= 0 && result < s.len()

fn last_index_of(s: Str, substr: Str) -> Option[Int]

Byte index of the last occurrence, or None.

  • Postcondition: result is Some(_) => result >= 0 && result <= s.len()

fn replace(s: Str, from: Str, to: Str) -> Str

Replace all occurrences of from with to.

fn lines(s: Str) -> Vec[Str]

Lines split on newlines (terminators removed).

  • Postcondition: result.len() >= 1

fn words(s: Str) -> Vec[Str]

Whitespace-separated words.

  • Precondition: true

fn is_empty(s: Str) -> Bool

True when the string has zero bytes.

  • Postcondition: result == (s.len() == 0)

fn is_empty(self: Self) -> Bool

Method form: x.is_empty(). The plain fn above is NOT a method -- the compiler's receiver-typed method lookup needs the Str receiver decl (method-form x.is_empty() otherwise falls through to a Vec/array is_empty leaf or a stub and always returns false).

  • Postcondition: result == (self.len() == 0)

fn char_count(s: Str) -> Int

Number of UTF-8 characters.

  • Postcondition: result >= 0

fn byte_count(s: Str) -> Int

Number of bytes.

  • Postcondition: result >= 0

fn str_index_of(haystack: Str, needle: Str) -> Option[Int]

Returns the first byte index of needle in haystack, or None if not found. O(n*m) naive search. For an empty needle, returns Some(0).

  • Precondition: needle.len() > 0

fn str_rindex_of(haystack: Str, needle: Str) -> Option[Int]

Returns the last byte index of needle in haystack, or None if not found. O(n*m) reverse naive search. For an empty needle, returns Some(haystack.len()).

  • Postcondition: result is Some(_) => result >= 0 && result <= haystack.len()

fn str_replace_all(s: Str, from_needle: Str, to_replacement: Str) -> Str

Replaces every occurrence of from with to in s. O(n*m) where n = |s|, m = |from|. If from is empty, returns s unchanged.

  • Precondition: from_needle.len() > 0

fn str_repeat(s: Str, n: Int) -> Str

Repeats s n times. Returns empty string if n <= 0. O(n * |s|) using repeated concatenation.

  • Postcondition: n <= 0 => result.len() == 0

fn str_pad_left(s: Str, width: Int, pad: Char) -> Str

Left-pads s with pad until the string reaches width bytes. If s is already >= width in bytes, returns s unchanged. O(width - |s|). Only handles single-byte pad characters correctly.

  • Postcondition: result.len() >= s.len()

fn str_pad_right(s: Str, width: Int, pad: Char) -> Str

Right-pads s with pad until the string reaches width bytes. If s is already >= width in bytes, returns s unchanged. O(width - |s|). Only handles single-byte pad characters correctly.

  • Postcondition: result.len() >= s.len()

fn str_strip_prefix(s: Str, prefix: Str) -> Option[Str]

If s starts with prefix, returns Some(s without prefix). Otherwise returns None. O(|prefix|).

fn str_strip_suffix(s: Str, suffix: Str) -> Option[Str]

If s ends with suffix, returns Some(s without suffix). Otherwise returns None. O(|suffix|).

fn str_escape(s: Str) -> Str

Escapes special characters (\n, \t, \", \, \r) in s. Returns a new string with escape sequences replaced by their literal representations. O(|s|). For multi-byte UTF-8 chars, only \n \t \" \ \r are escaped.

  • Precondition: true

fn str_unescape(s: Str) -> Str

Un-escapes a string that contains escape sequences like \n \t \" \ \r. Returns the string with literal escape sequences replaced by the actual characters. O(|s|). Unrecognised escape sequences are left unchanged.

  • Precondition: true

fn str_title_case(s: Str) -> Str

Converts s to Title Case: first character of each space-separated word is uppercased, remaining characters are lowercased. O(|s|) byte-by-byte. Only handles ASCII letter case correctly.

  • Postcondition: result.len() == s.len()

fn str_swap_case(s: Str) -> Str

Swaps the case of every character in s: uppercase becomes lowercase and vice versa. Characters that are neither are left unchanged. O(|s|) byte-by-byte. Only handles ASCII letter case correctly.

  • Postcondition: result.len() == s.len()

fn str_is_empty(s: Str) -> Bool

Returns true if s has zero length. O(1).

  • Postcondition: result == (s.len() == 0)

fn str_reverse(s: Str) -> Str

Reverses the characters in s. Unicode-aware: iterates by proper UTF-8 character boundaries. O(|s|) -- two passes (collect + build).

  • Postcondition: result.len() == s.len()

fn str_count_chars(s: Str) -> Int

Counts the number of Unicode characters in s using xiom_char_at. Unicode-aware: advances by the byte length of each character. O(|s|).

  • Postcondition: result >= 0

fn str_truncate_utf8(s: Str, max_bytes: Int) -> Str

Truncates s at the given byte position max_bytes, ensuring the result does not split a multi-byte UTF-8 character. If max_bytes lands in the middle of a multi-byte sequence, the result is truncated before that character begins. O(|s|).

  • Postcondition: max_bytes >= 0 => result.len() <= max_bytes

fn str_center(s: Str, width: Int) -> Str

Centers s within a field of width bytes by adding spaces on both sides. If an odd number of spaces are needed, the extra space goes on the right. Only handles single-byte pad characters correctly. O(width).

  • Postcondition: result.len() >= s.len()

fn str_starts_with_any(s: Str, prefixes: &Vec[Str]) -> Bool

Returns true if s starts with any of the given prefixes. O(n * k) where n = |s|, k = prefixes.len().

  • Postcondition: prefixes.len() == 0 => result == false

fn str_ends_with_any(s: Str, suffixes: &Vec[Str]) -> Bool

Returns true if s ends with any of the given suffixes. O(n * k) where n = |s|, k = suffixes.len().

  • Postcondition: suffixes.len() == 0 => result == false

fn str_contains_any(s: Str, needles: &Vec[Str]) -> Bool

Returns true if s contains any of the given substrings. O(n * m * k) where n = |s|, m = max substring length, k = needles.len().

  • Postcondition: needles.len() == 0 => result == false

fn str_translate(s: Str, from: Str, to: Str) -> Str

Translate characters per the tr utility: each char of s found in from is replaced by the char at the same position in to; chars beyond to's length are REMOVED; chars not in from pass through. ASCII.

  • Postcondition: result.len() <= s.len()

fn str_rot13(s: Str) -> Str

ROT13 over A-Z/a-z (ASCII).

  • Postcondition: result.len() == s.len()

fn str_rot47(s: Str) -> Str

ROT47 over ASCII 33..126 (all printable chars rotate by 47).

  • Postcondition: result.len() == s.len()

fn str_caesar(s: Str, shift: Int) -> Str

Caesar shift over A-Z/a-z (ASCII). Negative shifts go backwards; the shift wraps mod 26.

  • Postcondition: result.len() == s.len()

fn str_atbash(s: Str) -> Str

Atbash: a<->z, A<->Z mirror (ASCII). Non-letters pass through.

  • Postcondition: result.len() == s.len()

fn str_abbreviate(s: Str, max_len: Int) -> Str

Abbreviate with a middle ellipsis: keeps (max_len-3)/2 chars from the front and the rest from the back ("..." as "..."). Strings at or under max_len are returned unchanged; max_len < 4 falls back to truncation.

  • Postcondition: result.len() <= s.len()

fn str_obfuscate(s: Str, visible: Int) -> Str

Obfuscate: keep the first visible chars, mask the rest with '' (e.g. str_obfuscate("secret", 3) == "sec**"). visible < 0 -> 0.

  • Postcondition: result.len() == s.len()


strip.xi

fn str_strip_prefix(s: Str, prefix: Str) -> Option[Str]

If s starts with prefix, returns Some(s without the prefix). Returns None when s does not start with prefix. Complexity: O(|prefix|).

fn str_strip_suffix(s: Str, suffix: Str) -> Option[Str]

If s ends with suffix, returns Some(s without the suffix). Returns None when s does not end with suffix. Complexity: O(|suffix|).

fn str_strip_whitespace(s: Str) -> Str

Removes all whitespace characters from s. Returns a new string no longer than s. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()
fn str_strip_control(s: Str) -> Str

Removes all control characters from s. Returns a new string no longer than s. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()



template.xi

type Template

Compiled template: the original template text and the distinct named placeholders it contains, in first-seen order. Constructed only by template_compile.

Field Type
source Str
placeholders Vec[Str]
type Map

String map used by the render entry points: keys and values are parallel vectors of equal length. map_new / map_insert build maps.

Field Type
keys Vec[Str]
values Vec[Str]
fn map_new() -> Map

Create an empty string map. Params: none. Returns: an empty Map. Complexity: O(1).

fn map_insert(m: &mut Map, key: Str, value: Str)

Insert or replace key with value in m. Params: m the map to mutate; key, value the pair to store. Returns: nothing. Complexity: O(|m|).

fn template_compile(tpl: Str) -> Result[Template, Str]

Parse tpl into a compiled Template, validating placeholder syntax. The Template holds the source text and the distinct placeholder names. Params: tpl the template text. Returns: Ok with the compiled Template, Err on malformed placeholders. Error case: unclosed placeholder, empty name, lone brace. Complexity: O(|tpl|).

fn template_render_compiled(t: &Template, values: &Map) -> Result[Str, Str]

Render a compiled template using values. Placeholders missing from the map render as the empty string. Params: t the compiled template; values the value map. Returns: Ok with the rendered string. Error case: none (the template was already validated at compile time). Complexity: O(|tpl| + |placeholders| * |map|).

fn template_render(tpl: Str, values: &Map) -> Result[Str, Str]

Parse and render tpl, substituting placeholders from values. Placeholders missing from the map render as the empty string. Params: tpl the template text; values the value map. Returns: Ok with the rendered string, Err on malformed placeholder syntax. Error case: unclosed placeholder, empty name, lone brace. Complexity: O(|tpl| + |placeholders| * |map|).

fn template_render_map(tpl: Str, keys: &Vec[Str], values: &Vec[Str]) -> Result[Str, Str]

Parse and render tpl, pairing keys with values positionally. A key with no corresponding value renders as the empty string. Params: tpl the template text; keys, values the parallel vectors. Returns: Ok with the rendered string, Err on malformed placeholder syntax. Error case: unclosed placeholder, empty name, lone brace. Complexity: O(|tpl| + |placeholders| * |keys|).

fn template_render_fallback(tpl: Str, values: &Map, fallback: Str) -> Result[Str, Str]

Parse and render tpl, using fallback for placeholders missing from values. Params: tpl the template text; values the value map; fallback the value used for missing placeholders. Returns: Ok with the rendered string, Err on malformed placeholder syntax. Error case: unclosed placeholder, empty name, lone brace. Complexity: O(|tpl| + |placeholders| * |map|).

fn template_render_strict(tpl: Str, values: &Map) -> Result[Str, Str]

Parse and render tpl, returning Err when any placeholder is missing from values. Params: tpl the template text; values the value map. Returns: Ok with the rendered string, Err on malformed syntax or a missing value. Error case: unclosed placeholder, empty name, lone brace, missing value. Complexity: O(|tpl| + |placeholders| * |map|).

fn template_escape(s: Str) -> Str

Escape literal text so "{{" and "}}" render verbatim: every backslash, brace, or backslash-escaped sequence becomes a \-prefixed literal that the renderer copies unchanged. Params: s the literal text to escape. Returns: the escaped text. Error case: none. Complexity: O(|s|).

fn template_unescape(s: Str) -> Str

Reverse of template_escape: restores "{{" and "}}" from their escaped forms. Only \{, \} and \\ are unescaped; other backslash sequences pass through unchanged. Params: s the escaped text. Returns: the restored text. Error case: none. Complexity: O(|s|).

fn template_has_placeholders(tpl: Str) -> Bool

Return true when tpl contains at least one well-formed "{{name}}" placeholder (tolerant scan: malformed sequences do not count). Params: tpl the template text. Returns: true when a placeholder is present. Complexity: O(|tpl|).

fn template_placeholders(tpl: Str) -> Vec[Str]

The distinct placeholder names in tpl, in first-seen order (tolerant scan; malformed sequences are skipped). Params: tpl the template text. Returns: a Vec[Str] of distinct names. Complexity: O(|tpl|).

fn template_placeholder_count(tpl: Str) -> Int

Total number of placeholder occurrences in tpl (tolerant scan). Params: tpl the template text. Returns: the placeholder count. Complexity: O(|tpl|).

  • Postcondition: result >= 0
fn template_validate(tpl: Str) -> Result[(), Str]

Validate tpl: checks for balanced, well-formed "{{name}}" placeholders. Params: tpl the template text. Returns: Ok(()) when valid, Err describing the first problem. Error case: unclosed placeholder, empty name, lone brace, braces in a name. Complexity: O(|tpl|).




titlecase.xi

fn str_titlecase(s: Str) -> Str

Converts s to title case: the first character of each whitespace-separated word is uppercased and the remaining characters are lowercased. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn str_titlecase_words(s: Str) -> Str

Converts each word of s to title case, exactly like str_titlecase. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()



trim.xi

fn str_trim(s: Str) -> Str

Removes leading and trailing whitespace from s. Returns a new string no longer than s. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()
fn str_trim_start(s: Str) -> Str

Removes leading whitespace from s. Returns a new string no longer than s. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()
fn str_trim_end(s: Str) -> Str

Removes trailing whitespace from s. Returns a new string no longer than s. Complexity: O(|s|).

  • Postcondition: result.len() <= s.len()
fn str_trim_matches(s: Str, chars: Str) -> Str

Removes leading and trailing characters listed in chars from s. When chars is empty, s is returned unchanged. Returns a new string no longer than s. Complexity: O(|s| * |chars|).

  • Postcondition: result.len() <= s.len()
fn str_trim_start_matches(s: Str, chars: Str) -> Str

Removes leading characters listed in chars from s. When chars is empty, s is returned unchanged. Returns a new string no longer than s. Complexity: O(|s| * |chars|).

  • Postcondition: result.len() <= s.len()
fn str_trim_end_matches(s: Str, chars: Str) -> Str

Removes trailing characters listed in chars from s. When chars is empty, s is returned unchanged. Returns a new string no longer than s. Complexity: O(|s| * |chars|).

  • Postcondition: result.len() <= s.len()



truncate.xi

fn str_truncate(s: Str, max_len: Int) -> Str

Truncates s to at most max_len Unicode characters, cutting only at character boundaries. max_len < 0 yields the empty string; a string at or under the limit is returned unchanged. Params: s the source string; max_len the character limit. Returns: the truncated string (result.len() <= s.len()). Error case: "" when max_len < 0. Complexity: O(s.len()).

  • Postcondition: result.len() <= s.len()
fn str_truncate_utf8(s: Str, max_bytes: Int) -> Str

Truncates s to at most max_bytes bytes, cutting only at a UTF-8 boundary so no multi-byte character is split. A string at or under the limit is returned unchanged; max_bytes <= 0 yields the empty string. Params: s the source string; max_bytes the byte limit. Returns: the truncated string. Error case: "" when max_bytes <= 0. Complexity: O(s.len()).

  • Postcondition: result.len() <= s.len()
fn str_truncate_middle(s: Str, max_len: Int) -> Str

Truncates s keeping both ends and removing the middle: the first half of the budget comes from the front, the second half from the back. A string at or under max_len characters is returned unchanged; max_len < 0 yields the empty string. Params: s the source string; max_len the character budget. Returns: the head+tail string (result.len() <= s.len()). Error case: "" when max_len < 0. Complexity: O(s.len()).

  • Postcondition: result.len() <= s.len()
fn str_truncate_with_ellipsis(s: Str, max_len: Int) -> Str

Truncates s to max_len characters appending an ellipsis: the result is (max_len - 3) leading characters followed by "...". For limits too small to hold an ellipsis (max_len <= 3) plain truncation is used; a string at or under the limit is returned unchanged; max_len < 0 yields the empty string. Params: s the source string; max_len the total length including "...". Returns: the truncated-with-ellipsis string. Error case: "" when max_len < 0. Complexity: O(s.len()).

  • Postcondition: result.len() <= s.len()



unescape.xi

fn str_unescape(s: Str) -> Str

Interpret the common escape sequences in s back into literal characters: \n, \t, \r, \" and \. Unrecognised backslash sequences are left unchanged, so str_escape followed by str_unescape round-trips. Params: s the string containing escape sequences. Returns: the unescaped string. Error case: none. Complexity: O(|s|).

fn str_unescape_ascii(s: Str) -> Str

Interpret only the ASCII escapes in s: \n, \t and \xNN (exactly two hex digits, producing the raw byte). Every other sequence, including \" and \, passes through unchanged. Params: s the string containing escape sequences. Returns: the unescaped string. Error case: none; a malformed \xNN (fewer than two hex digits) is kept. Complexity: O(|s|).

fn str_unescape_unicode(s: Str) -> Str

Interpret the Unicode escapes in s: \uNNNN (exactly four hex digits) and \UNNNNNNNN (exactly eight hex digits), producing the UTF-8 encoding of the code point. Every other sequence passes through unchanged. Params: s the string containing escape sequences. Returns: the unescaped string. Error case: none; a malformed escape (wrong digit count) is kept verbatim. Complexity: O(|s|).




unicode.xi

fn unicode_normalize(s: Str) -> Str

Normalize s to NFC (canonical composition). See the normalize module.

fn unicode_normalize_nfc(s: Str) -> Str

Normalize s to NFC (canonical composition).

fn unicode_normalize_nfd(s: Str) -> Str

Normalize s to NFD (canonical decomposition).

fn unicode_normalize_nfkc(s: Str) -> Str

Normalize s to NFKC (compatibility composition).

fn unicode_normalize_nfkd(s: Str) -> Str

Normalize s to NFKD (compatibility decomposition).

fn unicode_normalize_form(s: Str, form: Str) -> Str

Normalize s using the named form "NFC", "NFD", "NFKC" or "NFKD" (case-insensitive). Unknown forms return s unchanged.

fn unicode_is_normalized(s: Str, form: Str) -> Bool

True when s is already normalized to the named form.

fn unicode_compose_pair(a: Char, b: Char) -> Option[Char]

Canonical composition of a + b (b a combining mark), None when not composable. Covers ASCII + Latin-1 accents.

fn unicode_decompose(c: Char) -> Vec[Char]

Canonical decomposition of one char: the base + combining marks, or the char itself when undecomposable. NOTE: Vec[Char] stores 1 byte per element (COMPILER_BUGS.md BUG 12), so codepoints above U+00FF in the result are truncated; prefer unicode_normalize_nfd for exact decomposition.

fn unicode_combining_sequence(s: Str) -> Vec[Str]

Split s into runs of a base character plus its trailing combining marks.

fn unicode_nfc_quick_check(s: Str) -> Bool

Fast check: true when s is already NFC.

  • Postcondition: result == (unicode_normalize_nfc(s) == s)
fn unicode_nfkc_quick_check(s: Str) -> Bool

Fast check: true when s is already NFKC.

  • Postcondition: result == (unicode_normalize_nfkc(s) == s)
fn unicode_casefold(s: Str) -> Str

Full case folding of s for caseless comparison.

fn unicode_casefold_char(c: Char) -> Char

Simple 1:1 case fold of one char (ASCII/Latin-1/Greek/Cyrillic).

fn unicode_casefold_turkic(s: Str) -> Str

Case fold of s using the Turkic I/U-dotted rules.

fn unicode_titlecase(s: Str) -> Str

Titlecase transform: the first cased letter of each word uppercased.

fn unicode_titlecase_word(s: Str) -> Str

Titlecase only the first word of s, leaving the rest unchanged.

fn unicode_lowercase_map(c: Char) -> Char

Simple 1:1 lowercase mapping of c, c itself when none exists.

fn unicode_uppercase_map(c: Char) -> Char

Simple 1:1 uppercase mapping of c, c itself when none exists.

fn unicode_tolower_full(s: Str) -> Str

Full lowercase of s (1:1 mappings; no multi-char expansions).

fn unicode_toupper_full(s: Str) -> Str

Full uppercase of s (1:1 mappings; no multi-char expansions).

fn unicode_titlecase_map(c: Char) -> Char

Simple 1:1 titlecase mapping of c (capital form).

fn unicode_istitlecase(c: Char) -> Bool

True when c is a titlecase letter (Lt).

fn unicode_grapheme_clusters(s: Str) -> Vec[Str]

Split s into extended grapheme clusters (simplified: base + combining marks + ZWJ sequences + emoji modifiers).

  • Postcondition: result.len() >= 0
fn unicode_grapheme_count(s: Str) -> Int

Number of extended grapheme clusters in s.

  • Postcondition: result >= 0
fn unicode_word_boundaries(s: Str) -> Vec[Int]

Byte offsets of word boundaries in s.

  • Postcondition: result.len() >= 0
fn unicode_word_count(s: Str) -> Int

Number of words in s.

  • Postcondition: result >= 0
fn unicode_sentence_boundaries(s: Str) -> Vec[Int]

Byte offsets of sentence boundaries in s.

  • Postcondition: result.len() >= 0
fn unicode_sentence_count(s: Str) -> Int

Number of sentences in s.

  • Postcondition: result >= 0
fn unicode_line_break_points(s: Str) -> Vec[Int]

Byte offsets of allowed line break points in s.

  • Postcondition: result.len() >= 0
fn unicode_line_breaks(s: Str) -> Vec[Str]

Split s into lines at the allowed break points.

  • Postcondition: result.len() >= 0
fn unicode_next_grapheme(s: Str, offset: Int) -> Int

Byte offset just past the grapheme starting at offset.

  • Postcondition: result >= 0
fn unicode_prev_grapheme(s: Str, offset: Int) -> Int

Byte offset of the grapheme start ending before offset.

  • Postcondition: result >= 0
fn unicode_ea_width(c: Char) -> Int

East Asian Width of c: 0, 1 or 2.

  • Postcondition: result >= 0
fn unicode_display_width(s: Str) -> Int

Total display width of s in cells.

  • Postcondition: result >= 0
fn unicode_truncate_display(s: Str, max_width: Int) -> Str

Truncate s to fit max_width display cells (grapheme-safe).

  • Postcondition: result.len() <= s.len()
fn unicode_pad_display(s: Str, width: Int, side: Str) -> Str

Pad s to a display width; side "left", "right" or "center".

  • Postcondition: result.len() >= s.len()
fn unicode_display_slice(s: Str, start: Int, end: Int) -> Str

Substring of s bounded by display-cell offsets start and end.

  • Postcondition: result.len() <= s.len()
fn unicode_is_wide(c: Char) -> Bool

True when c has East Asian Width W or F.

  • Postcondition: result == (ea_width.unicode_ea_width(c) == 2)
fn unicode_is_emoji(c: Char) -> Bool

True when c is an emoji or emoji component codepoint.

  • Postcondition: result == emoji.unicode_is_emoji(c)
fn unicode_count_emoji(s: Str) -> Int

Number of emoji characters and components in s.

  • Postcondition: result >= 0
fn unicode_has_emoji(s: Str) -> Bool

True when s contains at least one emoji.

fn unicode_emoji_presentation(c: Char) -> Bool

True when c defaults to emoji presentation (not text).

fn unicode_emoji_sequences(s: Str) -> Vec[Str]

Extract full emoji sequences (ZWJ joins, skin-tone modifiers, keycaps, regional-indicator flag pairs) from s.

  • Postcondition: result.len() >= 0
fn unicode_emoji_modifier(c: Char) -> Bool

True when c is an emoji modifier (skin tone).

fn unicode_emoji_zwj(c: Char) -> Bool

True when c is the ZWJ emoji joiner (U+200D).

fn unicode_emoji_version() -> Str

Emoji version implemented by the tables.

fn unicode_script(c: Char) -> Str

ISO 15924 script code of c.

  • Postcondition: result.len() == 4
fn unicode_script_name(code: Str) -> Str

Long English script name for an ISO 15924 code.

fn unicode_block(c: Char) -> Str

Unicode block name containing c, e.g. "Basic Latin".

fn unicode_general_category(c: Char) -> Str

Short general category of c, e.g. "Lu", "Nd", "Zs".

  • Postcondition: result.len() == 2
fn unicode_general_category_name(c: Char) -> Str

Long general category name of c, e.g. "Uppercase_Letter".

fn unicode_age(c: Char) -> Str

Unicode age of c as a version string (approximate for the compact table).

fn unicode_combining_class(c: Char) -> Int

Canonical combining class of c, 0 when spacing.

  • Postcondition: result >= 0
fn unicode_is_letter(c: Char) -> Bool

True when c is in a letter category (L*).

fn unicode_is_digit(c: Char) -> Bool

True when c is a decimal digit (Nd).

fn unicode_is_punct(c: Char) -> Bool

True when c is punctuation (P*).

fn unicode_is_symbol(c: Char) -> Bool

True when c is a symbol (S*).

fn unicode_is_separator(c: Char) -> Bool

True when c is a separator (Z*).

fn unicode_is_control(c: Char) -> Bool

True when c is a control or format character (Cc, Cf, Cs, Co, Cn).

fn unicode_is_printable(c: Char) -> Bool

True when c is printable (not control, format or unassigned).

fn unicode_script_of(s: Str) -> Str

Dominant script of s by character count; "Zzzz" for empty input.

  • Postcondition: result.len() == 4
  • Postcondition: s.len() == 0 => result == "Zzzz"
fn unicode_scripts(s: Str) -> Vec[Str]

Distinct scripts present in s, in first-seen order.

  • Postcondition: result.len() <= s.len()
fn unicode_is_ideographic(c: Char) -> Bool

True when c is in an ideographic range (Han, Hiragana, Katakana, Hangul).

fn unicode_bidi_class(c: Char) -> Str

Bidi class of c, e.g. "L", "R", "AL", "NSM".

fn unicode_mirrored(c: Char) -> Bool

True when c has the Bidi_Mirrored property.

fn unicode_mirror_char(c: Char) -> Char

Mirrored counterpart of c, c itself when not mirrored.

fn unicode_bidi_brackets(s: Str) -> Vec[Str]

Scan s for bidi bracket characters: one single-char string per bracket.

fn unicode_bidi_level(c: Char) -> Int

Implicit bidi embedding level of c: 0 (L), 1 (R/AL), 2 (EN/AN).

  • Postcondition: result >= 0
fn unicode_bidi_scan(s: Str) -> Vec[Int]

Resolved bidi levels of each char of s (simplified UBA: base level from the first strong character, strong/weak resolved per the bidi class).

  • Postcondition: result.len() <= s.len()
fn unicode_is_whitespace(c: Char) -> Bool

True when c matches the White_Space property.

fn unicode_is_alphabetic(c: Char) -> Bool

True when c has the Alphabetic property (approximated by letter + marks).

fn unicode_is_cased(c: Char) -> Bool

True when c has the Cased property (uppercase/lowercase/titlecase).

fn unicode_is_numeric(c: Char) -> Bool

True when c has the Numeric_Type property.

fn unicode_decimal_value(c: Char) -> Option[Int]

Decimal numeric value of c (Nd), None when not a decimal digit.

  • Postcondition: result is Some(_) => result.value >= 0
fn unicode_digit_value(c: Char) -> Option[Int]

Digit numeric value of c (Nd and Nl/No digit forms), None otherwise.

  • Postcondition: result is Some(_) => result.value >= 0
fn unicode_numeric_value(c: Char) -> Option[Float64]

Full numeric value of c including fractions, None when none.

  • Postcondition: result is Some(_) => result.value >= 0



uppercase.xi

fn str_uppercase(s: Str) -> Str

Converts all characters of s to uppercase. Returns a new string with the same byte length as s. Complexity: O(|s|).

  • Postcondition: result.len() == s.len()
fn char_uppercase(c: Char) -> Char

Returns the uppercase variant of c, or c unchanged when c has no uppercase mapping. Complexity: O(1).




utf8.xi

fn utf8_encode(codepoint: Int) -> Result[Vec[UInt8], Str]

Encode a single Unicode codepoint (Int) into 1-4 UTF-8 bytes. Returns a Vec[UInt8] containing exactly the encoded bytes. Rejects codepoints outside the valid Unicode range [0, 0xD7FF] | [0xE000, 0x10FFFF]. Complexity: O(1).

  • Precondition: codepoint >= 0
  • Postcondition: result is Ok(_) => result.len() >= 1 && result.len() <= 4

fn utf8_decode_at(data: &Vec[UInt8], pos: Int) -> Result[Int, Str]

Decode a single UTF-8 codepoint from a byte slice at the given position. Returns Ok(codepoint) on success, Err(msg) on invalid bytes. Call utf8_seq_len on the first byte to know how many bytes to advance. Complexity: O(1).

  • Precondition: pos >= 0
  • Postcondition: result is Ok(_) => result >= 0 && result <= 1114111

fn utf8_seq_len(first_byte: Int) -> Int

Return the length (1-4) of a UTF-8 sequence given its first byte. Returns 1 for any invalid leading byte (conservative fallback). Complexity: O(1).

  • Postcondition: result >= 1 && result <= 4

fn utf8_validate(data: &Vec[UInt8]) -> Bool

Validate that a byte slice contains only well-formed UTF-8. Complexity: O(n) where n = data.len().

fn utf8_codepoint_count(data: &Vec[UInt8]) -> Int

Count the number of Unicode codepoints in a UTF-8 byte slice. Complexity: O(n) where n = data.len().

  • Postcondition: result >= 0

fn utf8_encode_str(codepoints: &Vec[Int]) -> Result[Vec[UInt8], Str]

Encode a sequence of codepoints into a UTF-8 byte vector. Returns Ok(Vec[UInt8]) on success, Err(msg) if any codepoint is invalid. Complexity: O(n) where n = codepoints.len().

  • Postcondition: codepoints.len() > 0 => result is Ok(_) => result.len() >= codepoints.len()

fn utf8_is_continuation(byte: Int) -> Bool

Returns true if the byte is a UTF-8 continuation byte (10xxxxxx). Complexity: O(1).

fn utf8_char_len(cp: Int) -> Int

Return the number of UTF-8 bytes needed to encode a codepoint. Complexity: O(1).

  • Postcondition: result >= 1 && result <= 4


wordbreak.xi

fn unicode_word_boundaries(s: Str) -> Vec[Int]

Byte offsets in s where a new word begins (the start of every word after the first), in increasing order. For "Hello,world" the offsets are [5, 6]. Params: s the string to analyse. Returns: the list of word-start byte offsets (may be empty). Error case: none; malformed UTF-8 bytes are skipped without boundaries. Complexity: O(|s| * log table size).

fn unicode_split_words(s: Str) -> Vec[Str]

Split s into word tokens at the word boundaries. Whitespace stays with the preceding token; consecutive punctuation forms one token. Params: s the string to split. Returns: the list of word substrings. Error case: none. Complexity: O(|s| + number of boundaries).




wrap.xi

fn str_wrap(s: Str, width: Int) -> Vec[Str]

Wraps s into lines no longer than width bytes (soft wrapping): words are kept whole and the width is measured in bytes; a single word longer than the width is hard-split to honour the limit. A width below 1 or an empty input yields an empty vector. Params: s the source string; width the maximum line width in bytes. Returns: a Vec[Str] of wrapped lines. Error case: width < 1 => empty vector. Complexity: O(|s|).

  • Postcondition: width < 1 => result.len() == 0
fn str_wrap_hard(s: Str, width: Int) -> Vec[Str]

Wraps s by breaking at exactly width bytes regardless of word boundaries. A width below 1 or an empty input yields an empty vector. Params: s the source string; width the chunk size in bytes. Returns: a Vec[Str] of fixed-width lines (the last may be shorter). Error case: width < 1 => empty vector. Complexity: O(|s|).

  • Postcondition: width < 1 => result.len() == 0
fn str_wrap_soft(s: Str, width: Int) -> Vec[Str]

Wraps s at word boundaries without ever splitting a word: words are packed greedily and a word longer than width becomes its own line. A width below 1 or an empty input yields an empty vector. Params: s the source string; width the maximum line width in bytes. Returns: a Vec[Str] of wrapped lines. Error case: width < 1 => empty vector. Complexity: O(|s|).

  • Postcondition: width < 1 => result.len() == 0
fn str_wrap_join(s: Str, width: Int, sep: Str) -> Str

Wraps s with str_wrap and joins the resulting lines with sep. A width below 1 yields the empty string. Params: s the source string; width the maximum line width in bytes; sep the line separator. Returns: the wrapped lines joined by sep. Error case: width < 1 => "". Complexity: O(|s|).

  • Postcondition: width < 1 => result.len() == 0