Library

std/string

String operations.

2 files lib/std/string/string.vader, lib/std/string/unicode.vader 39 exports

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.

Implements Iterator<char> next :: fn(self) -> [char, Continuation]
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
No description.
Implements Error message :: fn(self) -> 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

sstring 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

sstring the string read.
offseti64 byte offset into s.
substring the bytes expected there.

Returns

bool
starts_with :: fn(s: string, prefix: string) -> bool

True iff s starts with prefix. Byte-wise comparison.

Parameters

sstring No description.
prefixstring No description.

Returns

bool
ends_with :: fn(s: string, suffix: string) -> bool

True iff s ends with suffix. Byte-wise comparison.

Parameters

sstring No description.
suffixstring 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

sstring 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

astring left string.
bstring 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

astring No description.
bstring 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

sstring source string.
cchar codepoint to find.
min_indexi64 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

sstring source string.
cchar codepoint to find.
fromi64 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

sstring source string.
sepstring 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

partsstring[] segments to concatenate ; an empty array yields "".
sepstring 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

sstring source string.
oldstring literal substring to find.
newstring 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

sstring source string.
oldstring literal substring to replace.
newstring 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

sstring the fragment to repeat.
ni64 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

sstring string to search.
cchar 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

sstring 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

sstring 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

sstring 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

sstring 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

sstring 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

sstring the digits-only input.

Returns

i32 | ParseError the parsed integer, or ParseError on failure.

Errors

  • ParseError on 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

sstring the float input.

Returns

f64 | ParseError the parsed float.

Errors

  • ParseError on 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

sstring source string.
widthi64 target length in codepoints.
fillchar 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

sstring source string.
widthi64 target length in codepoints.
fillchar 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

textsstring[] the column's entries.

Returns

i64 0 for no entries.

Example

widest(["a", "abc", "ab"])   // 3
wrap_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

textstring the text to wrap, on one line.
widthi64 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

sstring No description.
suffixstring 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

sstring No description.
prefixstring 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

bodystring 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

sstring source string.
predfn(char) -> bool predicate over each codepoint.
replacementstring 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

sstring source string.
predfn(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 byte
  • U+0080..U+07FF → 2 bytes
  • U+0800..U+FFFF → 3 bytes
  • U+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

cchar 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

unitu32 No description.

Returns

bool
is_low_surrogate :: fn(unit: u32) -> bool

True for a low (trailing) surrogate code unit, 0xDC00..0xDFFF.

Parameters

unitu32 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

unitu32 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

hiu32 the high surrogate (0xD800..0xDBFF).
lou32 the low surrogate (0xDC00..0xDFFF).

Returns

char the recombined scalar in U+10000..U+10FFFF.

Constants

MAX_CODEPOINT

const type inferred unicode.vader:14
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>
No description.

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
No description.
Written by vader doc. Icons: Codicons, CC BY 4.0. Fonts: Atkinson Hyperlegible, JetBrains Mono, OFL.