Skip to content

std/string

String operations including text-specific ops (split, replace, join, reverse, …) and the grapheme-cluster iterator used to drive lazy iter pipelines over a String. Transform graphemes with Iter.map(s, f) |> Iter.to_string(); materialize any Iterable<String> back with Iter.to_string.

Import with import std/string.

type String

UTF-8 encoded string.

fn contains?(s: String, substr: String): Bool

type function on String

Returns true if the string contains the substring.

Interactive Tests

assert String.contains?("hello world", "world")
refute String.contains?("hello", "xyz")
fn starts_with?(s: String, prefix: String): Bool

type function on String

True if s begins with the given prefix.

Interactive Tests

assert String.starts_with?("hello", "he")
fn ends_with?(s: String, suffix: String): Bool

type function on String

True if s ends with the given suffix.

Interactive Tests

assert String.ends_with?("hello.txt", ".txt")
fn to_upper(s: String): String

type function on String

Upper-cases s (Unicode-aware, locale-independent).

Interactive Tests

assert String.to_upper("café") == "CAFÉ"
fn to_lower(s: String): String

type function on String

Lower-cases s (Unicode-aware, locale-independent).

Interactive Tests

assert String.to_lower("CAFÉ") == "café"
fn replace(s: String, old: String, new: String): String

type function on String

Replaces every non-overlapping occurrence of old with new.

Interactive Tests

assert String.replace("a.b.c", ".", "-") == "a-b-c"
fn repeat(s: String, count: Int): String

type function on String

Concatenates count copies of s. A negative count is a runtime error.

Interactive Tests

assert String.repeat("ab", 3) == "ababab"
fn reverse(s: String): String

type function on String

Reverses s by grapheme cluster, so multi-code-point clusters (combining marks, ZWJ emoji) stay intact.

Interactive Tests

assert String.reverse("abc") == "cba"
fn normalize(s: String, form: NormalForm): String

type function on String

Returns s in the given Unicode normalization form.

Interactive Tests

assert String.normalize("é", NormalForm.NFC) == "é"
assert String.normalize("é", NormalForm.NFD) == "é"
fn slice(s: String, start: Int, end: Int): String

type function on String

Returns a substring from start index to end index (grapheme-based, start inclusive, end exclusive).

Interactive Tests

assert String.slice("hello", 1, 4) == "ell"
fn join(parts: List<String>, separator: String): String

type function on String

Joins a list of strings with a separator between each element.

Interactive Tests

assert String.join(["a", "b", "c"], ", ") == "a, b, c"
assert String.join([], ", ") == ""
fn split(s: String, separator: String): List<String>

type function on String

Splits a string into a list of substrings on every occurrence of separator. The separator itself is consumed and never appears in the output. Adjacent occurrences of separator produce empty-string entries. An empty separator splits at every UTF-8 codepoint boundary (one entry per codepoint). Inverse of String.join.

Interactive Tests

assert String.split("a,b,c", ",") == ["a", "b", "c"]
assert String.split("a, b, c", ", ") == ["a", "b", "c"]
assert String.split(",a,", ",") == ["", "a", ""]
assert String.split("hello", "") == ["h", "e", "l", "l", "o"]
fn trim(s: String): String

type function on String

Returns s with leading and trailing whitespace removed (spaces, tabs, newlines, carriage returns — Go’s strings.TrimSpace rules). Inner whitespace is preserved.

Interactive Tests

assert String.trim("  hello  ") == "hello"
assert String.trim("\n\tworld\n") == "world"
assert String.trim("a  b") == "a  b"
fn to_int(s: String): Maybe<Int>

type function on String

Parses s as a base-10 signed integer. Returns Some(n) on success, None on any failure (non-digit characters, empty string, out-of-range value). Leading/trailing whitespace is tolerated.

Interactive Tests

assert String.to_int("42") == Some(42)
assert String.to_int("-7") == Some(-7)
assert String.to_int("  3  ") == Some(3)
assert String.to_int("abc") == None
assert String.to_int("") == None
fn graphemes(s: String): List<String>

type function on String

Splits a string into a list of grapheme clusters (one per user-visible character).

Interactive Tests

assert String.graphemes("abc") == ["a", "b", "c"]
fn bytes(s: String): List<Int>

type function on String

Returns the raw bytes of the string (UTF-8 encoded) as a list of Ints.

Interactive Tests

assert String.bytes("ab") == [97, 98]
fn codepoints(s: String): List<Codepoint>

type function on String

Returns the Unicode codepoints of the string as scalar values.

Interactive Tests

assert "ab"
  |> String.codepoints()
  |> Iter.map(Codepoint.to_int)
  |> Iter.to_list()
  |> List.equal?([97, 98])
fn strip_prefix(s: String, prefix: String): Maybe<String>

type function on String

Strips a prefix from the string. Returns Some(rest) if the prefix matches, or None otherwise.

Interactive Tests

assert String.strip_prefix("hello world", "hello ") == Some("world")
assert String.strip_prefix("hello", "xyz") == None
fn strip_suffix(s: String, suffix: String): Maybe<String>

type function on String

Strips a suffix from the string. Returns Some(rest) if the suffix matches, or None otherwise.

Interactive Tests

assert String.strip_suffix("hello.txt", ".txt") == Some("hello")
assert String.strip_suffix("hello", "xyz") == None
fn length(s: String): Int

type function on String

Number of grapheme clusters in the string. O(1) (host-backed) — counts clusters directly instead of walking them. Grapheme-based, not byte-based: String.length("héllo") is 5. (String keeps its own length because the generic count, Iter.count, is the fold; this is the fast path.)

impl Iterable

fn next(s: String): Maybe<(String, String)>

impl Iterable.next

Returns the next grapheme cluster and remaining string, or None if empty.

impl Display

fn to_string(s: String): String

impl Display.to_string

impl Add

fn add(lhs: String, rhs: String): String

impl Add.add

impl Debug

fn inspect(s: String): String

impl Debug.inspect

impl Equatable

fn equal?(a: String, b: String): Bool

impl Equatable.equal?

impl Hashable

fn hash(s: String): Int

impl Hashable.hash

FNV-1a 64-bit hash of the UTF-8 bytes, reinterpreted as an Int. Stable within one runtime process; not cryptographic, not stable across runs.

impl Comparable

fn compare(a: String, b: String): Ordering

impl Comparable.compare

enum NormalForm {
    NFC
    NFD
    NFKC
    NFKD
}

Unicode normalization forms (UAX #15). Equality and hashing are byte-based, so two visually identical strings in different forms — a precomposed “é” (‘U+00E9) vs a decomposed “e” + U+0301 — are not ==. Normalize to a common form first when comparing text from mixed sources.

impl Display

fn to_string(value: NormalForm): String

impl Display.to_string

impl Debug

fn inspect(value: NormalForm): String

impl Debug.inspect