std/string
String operations.
All string operations treat strings as immutable UTF-8 byte sequences.
Types
StringChars :: struct Iterator yielding Unicode codepoints: one per UTF-8 sequence, regardless of whether the codepoint is encoded in 1, 2, 3, or 4 bytes. The cursor moves in bytes over the string itself.
ParseError :: struct Error raised by parse_int on malformed input. Also the canonical
parse-error type imported by std/numbers and std/semver.
Fields
msg: string Functions
is_empty :: fn(s: string) -> bool True for the empty string. Equivalent to s.byte_len() == 0 but
reads cleanly at call sites: emptiness is the same in byte and
codepoint views.
Parameters
| s | string | No description. |
Returns
bool matches_at :: fn(s: string, offset: i64, sub: string) -> bool True when sub occurs in s at byte offset. False when sub would run past
the end of s.
Parameters
| s | string | the string read. |
| offset | i64 | byte offset into s. |
| sub | string | the bytes expected there. |
Returns
bool starts_with :: fn(s: string, prefix: string) -> bool True iff s starts with prefix. Byte-wise comparison.
Parameters
| s | string | No description. |
| prefix | string | No description. |
Returns
bool ends_with :: fn(s: string, suffix: string) -> bool True iff s ends with suffix. Byte-wise comparison.
Parameters
| s | string | No description. |
| suffix | string | No description. |
Returns
bool chars :: fn(s: string) -> StringChars Iterate s codepoint-by-codepoint, as an iterator value: for c in s
walks the same codepoints through the Into<Iterator<char>> impl below,
without one. It walks s once, where s[i] walks from the start at
every index.
Parameters
| s | string | source string. |
Returns
StringChars a StringChars iterator over its codepoints.Example
letters :: "héllo".chars()compare_ascending :: fn(a: string, b: string) -> bool Comparator suitable for sort(arr, compare_ascending) : a < b as a
function value: byte order, which is codepoint order in UTF-8.
Parameters
| a | string | left string. |
| b | string | right string. |
Returns
bool true iff a strictly precedes b ; equal strings → false.compare_ascending_ci :: fn(a: string, b: string) -> bool Case-insensitive ASCII variant of compare_ascending. Matches
JavaScript's default String.localeCompare() ordering for the
ASCII subset (case-folded comparison ; ties broken by code point).
Parameters
| a | string | No description. |
| b | string | No description. |
Returns
bool last_index_of :: fn(s: string, c: char, min_index: i64) -> i64 Byte offset of the last occurrence of c in s at or after
min_index. Walks codepoint-by-codepoint (UTF-8 safe: the byte
cursor advances by each codepoint's encoded width), tracking the
latest match. Returns -1 when not found ; the signed i64
return type lets callers branch on result < 0 instead of folding
"absent" into a zero offset.
Parameters
| s | string | source string. |
| c | char | codepoint to find. |
| min_index | i64 | earliest leading-byte position to keep as a match (later matches still win). Pass 0 to accept every position. |
Returns
i64 byte offset of the latest match, or -1 if absent.index_of :: fn(s: string, c: char, from: i64) -> i64 Byte offset of the first occurrence of c in s, starting at
the codepoint that begins at byte from (inclusive). UTF-8 safe,
see last_index_of for the iteration model. from should align
to a leading byte ; out-of-range values short-circuit to -1.
Parameters
| s | string | source string. |
| c | char | codepoint to find. |
| from | i64 | earliest leading-byte position considered. |
Returns
i64 byte offset of the match, or -1 if absent.split :: fn(s: string, sep: string) -> string[] Split s on every occurrence of sep, returning the resulting
segments. Empty segments are preserved (between consecutive sep
runs and at the ends). For predicate-based splitting see
split_where.
Parameters
| s | string | source string. |
| sep | string | separator (matched byte-wise). Empty sep yields one segment per codepoint of s, holding the bytes codepoint_at_byte steps over. |
Returns
string[] array of segments ; never empty (at minimum, [""]), save split("", ""), which has no codepoint to give.join :: fn(parts: string[], sep: string) -> string Concatenate parts, inserting sep between consecutive elements.
The inverse of split: join(split(s, sep), sep) == s.
Parameters
| parts | string[] | segments to concatenate ; an empty array yields "". |
| sep | string | separator inserted between elements only (no leading or trailing copy). |
Returns
string the concatenation, or "" when parts is empty.replace :: fn(s: string, old: string, new: string) -> string Replace the first occurrence of old in s with new (literal substring,
not a pattern: use std/regex for pattern replacement). Returns s
unchanged when old does not occur.
Parameters
| s | string | source string. |
| old | string | literal substring to find. |
| new | string | replacement for the first match. |
Returns
string s with the first old replaced by new.replace_all :: fn(s: string, old: string, new: string) -> string Replace every occurrence of old in s with new (literal). Equivalent to
s.split(old).join(new). Use std/regex for pattern replacement.
Parameters
| s | string | source string. |
| old | string | literal substring to replace. |
| new | string | replacement for each match. |
Returns
string s with every old replaced by new.repeat :: fn(s: string, n: i64) -> string Concatenate n copies of s ; n == 0 yields the empty string.
Parameters
| s | string | the fragment to repeat. |
| n | i64 | how many copies. |
Returns
string s repeated n times.contains_char :: fn(s: string, c: char) -> bool True when codepoint c occurs in s: a char-presence predicate built on
index_of. For substring containment use sub in s (the Contains trait).
Parameters
| s | string | string to search. |
| c | char | codepoint to look for. |
Returns
bool whether c appears in s.trim :: fn(s: string) -> string Strip leading and trailing ASCII whitespace (' ', '\t', '\n',
'\r'). Unicode whitespace is not recognised in MVP.
Parameters
| s | string | No description. |
Returns
string left_trim :: fn(s: string) -> string Strip leading ASCII whitespace (' ', '\t', '\n', '\r') only ;
trailing whitespace is preserved. See trim for both ends.
Parameters
| s | string | source string. |
Returns
string s with its leading whitespace removed.right_trim :: fn(s: string) -> string Strip trailing ASCII whitespace (' ', '\t', '\n', '\r') only ;
leading whitespace is preserved. See trim for both ends.
Parameters
| s | string | source string. |
Returns
string s with its trailing whitespace removed.to_upper :: fn(s: string) -> string Uppercase s over ASCII and the Latin-1 Supplement (a..z, à..þ, ÿ).
UTF-8 aware: codepoints outside those ranges (incl. ß, non-Latin scripts)
pass through unchanged ; no full Unicode case tables.
Parameters
| s | string | No description. |
Returns
string to_lower :: fn(s: string) -> string Lowercase s over ASCII and the Latin-1 Supplement (A..Z, À..Þ, Ÿ).
UTF-8 aware: codepoints outside those ranges pass through unchanged ; no full
Unicode case tables.
Parameters
| s | string | No description. |
Returns
string parse_int :: fn(s: string) -> i32 | ParseError Parse s as a base-10 i32. No prefix, no underscores, no leading
+ sign ; a leading - is accepted.
Returns the explicit union i32 | ParseError : callers match the
concrete is ParseError (a plain field read) instead of is Error.
The existential Error-trait dispatch on a stdlib error value
mis-executes on the self-host VM ; the concrete-type match sidesteps it.
Parameters
| s | string | the digits-only input. |
Returns
i32 | ParseError the parsed integer, or ParseError on failure.Errors
ParseErroron empty input, malformed digit, or overflow.
parse_float :: fn(s: string) -> f64 | ParseError Parse s as an f64: sign, mantissa, optional exponent. Correctly rounded
: delegates to std/core::parse_f64 (Eisel-Lemire fast path + an exact
big-int slow path), so the VM and native backends agree bit-for-bit: unlike
the old strtod host, whose VM twin diverged on subnormals / long fractions.
Returns the explicit union f64 | ParseError (concrete, like parse_int) :
the existential Error-trait dispatch mis-executes on the self-host VM, so
callers match is ParseError.
Parameters
| s | string | the float input. |
Returns
f64 | ParseError the parsed float.Errors
ParseErroron malformed input.
pad_start :: fn(s: string, width: i64, fill: char) -> string Pad s on the LEFT with copies of fill until it holds width
codepoints. Returns s unchanged when it already holds at least
width. A codepoint is not a terminal column: a wide CJK glyph or a
combining mark still counts one.
Parameters
| s | string | source string. |
| width | i64 | target length in codepoints. |
| fill | char | pad character. |
Returns
string pad_end :: fn(s: string, width: i64, fill: char) -> string Pad s on the RIGHT with copies of fill until it holds width
codepoints. Symmetric with pad_start.
Parameters
| s | string | source string. |
| width | i64 | target length in codepoints. |
| fill | char | pad character. |
Returns
string widest :: fn(texts: string[]) -> i64 The most codepoints any of texts holds, as pad_end counts: the width a
column of them takes.
Parameters
| texts | string[] | the column's entries. |
Returns
i64 0 for no entries.Example
widest(["a", "abc", "ab"]) // 3wrap_words :: fn(text: string, width: i64) -> string[] Cut text at its spaces into lines of at most width codepoints. A word
longer than a line has a line of its own, and runs of spaces count as one.
Parameters
| text | string | the text to wrap, on one line. |
| width | i64 | the most codepoints a line holds. |
Returns
string[] the lines, at least one, "" for an empty text.Example
"the quick brown fox".wrap_words(9) // ["the quick", "brown fox"]trim_suffix :: fn(s: string, suffix: string) -> string Strip suffix if s ends with it ; otherwise return s unchanged.
Trims at most one occurrence.
Parameters
| s | string | No description. |
| suffix | string | No description. |
Returns
string trim_prefix :: fn(s: string, prefix: string) -> string Strip prefix if s starts with it ; otherwise return s unchanged.
Trims at most one occurrence.
Parameters
| s | string | No description. |
| prefix | string | No description. |
Returns
string decode_escapes :: fn(body: string) -> string Decode the common C-style escape sequences in body: \n (LF), \t (TAB),
\r (CR), \", \\ and \0 (NUL). A backslash at the very end of body is
preserved verbatim. A string with no backslash is returned as it is, without a
copy.
Lenient: an unknown escape (\q) drops its backslash and passes the following
byte through ("a\\qb" gives "aqb"), as the lexer and the VM parser do. A
caller that wants unknown escapes rejected validates beforehand.
Parameters
| body | string | the raw source bytes (without surrounding quotes). |
Returns
string the decoded string.Example
decode_escapes(r"a\nb\tc") // "a\nb\tc"
decode_escapes("plain") // "plain"replace_chars_where :: fn(s: string, pred: fn(char) -> bool, replacement: string) -> string Replace every codepoint that satisfies pred with replacement.
Subsumes the regex pattern replace(/[<class>]/g, "…").
Parameters
| s | string | source string. |
| pred | fn(char) -> bool | predicate over each codepoint. |
| replacement | string | string to substitute for each match. |
Returns
string a fresh string.split_where :: fn(s: string, pred: fn(char) -> bool) -> string[] Split s on runs of characters matching pred, dropping empty
segments. Mirrors replace_chars_where(s, pred, ...): same predicate
convention, same pair-with-is_* ergonomics. For whitespace
splitting, pass is_white_char ; for word-boundary splitting
(alphanumeric runs), pass c -> !c.is_alnum(). Empty inputs return
an empty array.
Parameters
| s | string | source string. |
| pred | fn(char) -> bool | predicate over each codepoint ; truthy → separator. |
Returns
string[] non-empty segments (in source order).Example
expand
import "std/char"
" hello\tworld ".split_where(is_white_char) // ["hello", "world"]
"a,b,,c".split_where(c -> c == ',') // ["a", "b", "c"]" hello\tworld ".split_where(is_white_char) // ["hello", "world"]
"a,b,,c".split_where(c -> c == ',') // ["a", "b", "c"]codepoint_byte_len :: fn(c: char) -> i64 UTF-8 encoded byte length (1–4) of codepoint c, as utf8_encode writes it:
U+0000..U+007F→ 1 byteU+0080..U+07FF→ 2 bytesU+0800..U+FFFF→ 3 bytesU+10000..U+10FFFF→ 4 bytes
The width a char takes once encoded, not the width it was decoded from:
codepoint_at_byte answers that one.
Parameters
| c | char | the codepoint to measure. |
Returns
i64 its UTF-8 encoded length in bytes (1, 2, 3, or 4).is_high_surrogate :: fn(unit: u32) -> bool True for a high (leading) surrogate code unit, 0xD800..0xDBFF.
Parameters
| unit | u32 | No description. |
Returns
bool is_low_surrogate :: fn(unit: u32) -> bool True for a low (trailing) surrogate code unit, 0xDC00..0xDFFF.
Parameters
| unit | u32 | No description. |
Returns
bool is_surrogate :: fn(unit: u32) -> bool True for either half of a surrogate pair, 0xD800..0xDFFF: no char holds
one, and a decoder that sees one in isolation substitutes REPLACEMENT_CHAR.
Parameters
| unit | u32 | No description. |
Returns
bool combine_surrogates :: fn(hi: u32, lo: u32) -> char Recombine a UTF-16 surrogate pair into the astral scalar it encodes. The
caller must have verified is_high_surrogate(hi) and is_low_surrogate(lo).
Parameters
| hi | u32 | the high surrogate (0xD800..0xDBFF). |
| lo | u32 | the low surrogate (0xDC00..0xDFFF). |
Returns
char the recombined scalar in U+10000..U+10FFFF.Constants
MAX_CODEPOINT: char :: char(0x10FFFF) The highest Unicode scalar value (U+10FFFF), @max(char). Codepoints above
this are invalid ; \u{...} escapes past it are rejected.
Implementations
Methods
into :: fn(self) -> Iterator<char> Lets sub in s desugar to s.contains(sub). The Contains trait
(std/core) is what the in operator dispatches through ; without this
impl in on string falls back to "language feature unsupported" at the
lower stage. The method delegates to the module-private byte_contains
(a byte-wise scan).
Methods
contains :: fn(self, sub: string) -> bool