Module string/index
String and Unicode types.
A re-export barrel: importing std/string gives you rune, everything in
./string.yo (String, StringError, its four iterators, Pattern,
FromString, the three parse-error enums) and everything in
./string_builder.yo (StringBuilder, Alignment). It defines nothing of
its own — the imports are _-prefixed so only the re-exported names cross
the boundary.
./unicode.yo is deliberately NOT re-exported: it is the leaf case-mapping
table String.to_lowercase / to_uppercase route through, not a surface a
caller reaches for.
Stability
unstable — only because what it forwards is. The barrel's own shape (one
import per file, one flat export list) is settled and adding a module to it
is additive, but it re-exports std/string/rune.yo, whose ASCII-only
is_* / to_*case methods are due a breaking rename, and
std/string/string.yo, which still carries the D10/D12 deprecated aliases
awaiting deletion. Both are named in those modules' own ## Stability
sections. This file freezes when they do.
Types
Unicode code point (U+0000 to U+10FFFF, excluding surrogates).
Similar to Go's rune or Rust's char.
Fields
| Name | Type | Description |
|---|---|---|
char | u32 | The raw Unicode code point value. |
Trait Implementations
impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> StringRender self under spec. An unrecognised spec degrades to the plain
to_string() rendering rather than failing.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Self | |
spec | str |
Returns: String
Methods
from_u32 : (rune) fn(value : u32) -> Option(rune)Create a rune from a u32 value, returning None if the value is not a valid Unicode code point.
Parameters
| Name | Type | Notes |
|---|---|---|
value | u32 |
Returns: Option(rune)
to_u32 : (rune) fn(self : rune) -> u32Return the raw u32 code point value.
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: u32
is_ascii : (rune) fn(self : rune) -> boolCheck if this is an ASCII character (U+0000 to U+007F).
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: bool
is_whitespace : (rune) fn(self : rune) -> boolCheck if this is a whitespace character (space, tab, newline, or carriage return).
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: bool
is_digit : (rune) fn(self : rune) -> boolCheck if this is an ASCII digit ('0' to '9').
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: bool
is_alphabetic : (rune) fn(self : rune) -> boolCheck if this is an ASCII letter ('A'-'Z' or 'a'-'z').
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: bool
is_uppercase : (rune) fn(self : rune) -> boolCheck if this is an ASCII uppercase letter ('A'-'Z').
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: bool
is_lowercase : (rune) fn(self : rune) -> boolCheck if this is an ASCII lowercase letter ('a'-'z').
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: bool
to_lowercase : (rune) fn(self : rune) -> runeConvert to lowercase. Only affects ASCII uppercase letters.
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: rune
to_uppercase : (rune) fn(self : rune) -> runeConvert to uppercase. Only affects ASCII lowercase letters.
Parameters
| Name | Type | Notes |
|---|---|---|
self | rune |
Returns: rune
== : (rune) fn(lhs : rune, rhs : rune) -> boolParameters
| Name | Type | Notes |
|---|---|---|
lhs | rune | |
rhs | rune |
Returns: bool
!= : (rune) fn(lhs : rune, rhs : rune) -> boolParameters
| Name | Type | Notes |
|---|---|---|
lhs | rune | |
rhs | rune |
Returns: bool
< : (rune) fn(lhs : rune, rhs : rune) -> boolParameters
| Name | Type | Notes |
|---|---|---|
lhs | rune | |
rhs | rune |
Returns: bool
<= : (rune) fn(lhs : rune, rhs : rune) -> boolParameters
| Name | Type | Notes |
|---|---|---|
lhs | rune | |
rhs | rune |
Returns: bool
> : (rune) fn(lhs : rune, rhs : rune) -> boolParameters
| Name | Type | Notes |
|---|---|---|
lhs | rune | |
rhs | rune |
Returns: bool
>= : (rune) fn(lhs : rune, rhs : rune) -> boolParameters
| Name | Type | Notes |
|---|---|---|
lhs | rune | |
rhs | rune |
Returns: bool
cmp : (rune) fn(lhs : rune, rhs : rune) -> Orderingdefault : (rune) fn() -> runeThe default value of the type.
Returns: rune
is_prefix_of : (rune) fn(self : rune, haystack : String, position : usize) -> boolis_suffix_of : (rune) fn(self : rune, haystack : String, end_position : usize) -> boolindex_in : (rune) fn(self : rune, haystack : String, from_index : usize) -> Option(usize)is_contained_in : (rune) fn(self : rune, haystack : String, from_index : usize) -> boollast_index_in : (rune) fn(self : rune, haystack : String, from_index : usize) -> Option(usize)length_in : (rune) fn(self : rune, haystack : String, at : usize) -> usizesplit_of : (rune) fn(self : rune, haystack : String) -> ArrayList(String)to_string : (rune) fn(self : rune) -> Stringdebug_string : (rune) fn(self : rune) -> StringGrowable UTF-8 encoded string — the same shape as Rust's String.
NOT immutable: push_str / push_string / push_byte / reserve / clear
take inout(self) and mutate in place. Operators such as + still return a
new string. For an immutable, atomically reference-counted string that is safe
to share across threads, see std/imm/string.
Empty strings use zero allocation (represented as Option.None internally).
Fields
| Name | Type | Description |
|---|---|---|
_bytes | Option(ArrayList(u8)) |
Trait Implementations
impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> StringRender self under spec. An unrecognised spec degrades to the plain
to_string() rendering rather than failing.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Self | |
spec | str |
Returns: String
Methods
new : (String) fn() -> StringCreate a new empty string (zero allocation)
Returns: String
with_capacity : (String) fn(capacity : usize) -> StringCreate a new empty string with pre-allocated capacity for the given number of bytes.
The string starts empty but can hold capacity bytes without reallocating.
Parameters
| Name | Type | Notes |
|---|---|---|
capacity | usize |
Returns: String
from_bytes : (String) fn(bytes : ArrayList(u8)) -> StringCreate a string from raw bytes WITHOUT checking that they are UTF-8.
This is the unchecked constructor: the caller guarantees validity, and
nothing scans the buffer. Use it when the bytes came from something that
already produced UTF-8 — another String, a UTF-8 encoder, a byte-exact
slice taken at rune boundaries. For bytes of unknown provenance (a file, a
socket, a subprocess) use from_utf8, which validates and reports where
the input went wrong.
Parameters
| Name | Type | Notes |
|---|---|---|
bytes | ArrayList(u8) |
Returns: String
from_utf8 : (String) fn(bytes : ArrayList(u8)) -> Result(String, StringError)Create a string from raw bytes, checking that they are valid UTF-8.
The checked counterpart to from_bytes: Err(StringError.InvalidUtf8)
carries a Utf8Error naming the defect and the byte offset it starts at.
Validation is a single linear scan through std/encoding/utf8.
Parameters
| Name | Type | Notes |
|---|---|---|
bytes | ArrayList(u8) |
Returns: Result(String, StringError)
from : (String) fn(slice : str) -> StringCreate a string from a slice of bytes str The slice is a fat pointer containing data pointer and length Example: String.from(slice) where slice is str
Parameters
| Name | Type | Notes |
|---|---|---|
slice | str |
Returns: String
from_cstr : (String) fn(cstr : *(u8)) -> Result(String, StringError)Create a string from a C null-terminated string *(u8) Copies bytes until it finds a null byte (0) Example: String.from_cstr(c_string_ptr)
Note: We manually search for the null terminator by iterating
Parameters
| Name | Type | Notes |
|---|---|---|
cstr | *(u8) |
Returns: Result(String, StringError)
to_cstr : (String) fn(self : String) -> ArrayList(u8)len : (String) fn(self : String) -> usizeNumber of BYTES in this string's UTF-8 encoding — O(1).
BYTE basis. This is the unit every index-taking method on String
speaks: at, substring, the s(a..b) / s(a..=b) slice sugar,
index_of, last_index_of, contains(from_index),
starts_with(position), ends_with(end_position) and the Pattern
trait. It agrees with str.len(), StringBuilder.len(), Index(usize)
(which yields a u8) and Rust's str::len().
For "how many runes" use chars().count() (O(n)); to walk runes together with
the byte offset each one starts at, use char_indices().
(plans/archive/STD_API_AUDIT_D4_PLAN.md D4 PR 3 — this returned a RUNE count
before that flip.)
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: usize
is_empty : (String) fn(self : String) -> boolas_bytes : (String) fn(self : String) -> ArrayList(u8)raw_bytes : (String) fn(self : String) -> RawSlice(u8)Get a str view into the string's UTF-8 bytes
Returns a fat pointer (pointer + length) without copying
PRIVILEGED raw view of the heap buffer (ptr + byte length) for C
interop and pragma'd std internals. Naming RawSlice requires
pragma(Pragma.AllowUnsafe); the view dangles if the String mutates
or dies — callers must not let it escape the borrow site.
(This replaces the deleted as_str(): heap bytes can no longer be
viewed as str, which is the STATIC string view.
See plans/archive/SLICE_REWORK.md.)
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: RawSlice(u8)
_decode_rune_at : (String) fn(self : String, byte_index : usize) -> Option(rune)is_char_boundary : (String) fn(self : String, index : usize) -> boolTrue when byte offset index sits on a rune boundary.
0 and len() are always boundaries; an index past the end never is.
Mirrors Rust's str::is_char_boundary. (Defined here, beside at and
substring, because an impl block cannot call forward into a later
one and both of those need it.)
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
index | usize |
Returns: bool
at : (String) fn(self : String, index : usize) -> Option(rune)Decode the rune that STARTS at byte offset index.
BYTE basis (plans/archive/STD_API_AUDIT_D4_PLAN.md D4 PR 3 — this took a
rune index before the flip). .None is returned for the three ways a
byte offset can fail to name a rune: at or past len(), inside a rune
(a UTF-8 continuation byte), or on bytes that do not decode.
while(i < s.len(), { s.at(i) }) therefore visits continuation bytes and
yields .None at each of them — use char_indices() (or chars()) to
walk runes.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
index | usize |
Returns: Option(rune)
concat : (String) fn(self : String, other : String) -> Stringpush_string : (String) fn(self : String, other : String) -> unitpush_str : (String) fn(self : String, s : str) -> unitAppend a str slice to this string in-place (mutates self).
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
s | str |
Returns: unit
push_byte : (String) fn(self : String, b : u8) -> unitAppend a single byte to this string in-place (mutates self).
The caller must ensure the byte maintains valid UTF-8.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
b | u8 |
Returns: unit
push_rune : (String) fn(self : String, r : rune) -> unitAppend one rune, UTF-8 encoded — Rust's String::push.
push_byte appends a single BYTE and will happily build invalid UTF-8;
this is the rune-level counterpart, so it is what you want for anything
outside ASCII.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
r | rune |
Returns: unit
reserve : (String) fn(self : String, additional : usize) -> unitReserve capacity for at least additional more bytes.
If the string is empty, creates a new buffer with the given capacity.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
additional | usize |
Returns: unit
clear : (String) fn(self : String) -> unitClear the string content but keep the allocated buffer for reuse.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: unit
byte_at : (String) fn(self : String, index : usize) -> u8Get the byte at the given index. Panics if the index is out of
bounds (mirrors str's byte indexing). Use len() for the
valid range and bytes() for sequential iteration.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
index | usize |
Returns: u8
substring : (String) fn(self : String, start : usize, end : usize) -> StringOwned copy of the bytes in [start, end).
BYTE basis (plans/archive/STD_API_AUDIT_D4_PLAN.md D4 PR 3 — these were
rune indices before the flip).
Boundary policy, in full:
- Out-of-range CLAMPS.
startandendpastlen()are pulled back tolen(), andstart >= endyields the empty string. This is the forgiving behavioursubstringhas always had, and it is kept. - A non-boundary index PANICS. An endpoint inside a rune is a programmer error — a byte offset that came from the wrong basis — not a range condition, and honouring it would hand back invalid UTF-8.
try_substring(start, end)is the non-panicking form: it returns.Nonefor a bad range instead of clamping or panicking.floor_char_boundary/ceil_char_boundarysnap an arbitrary offset onto a boundary first, for callers doing byte arithmetic.- Rune-indexed slicing has no method form — walk
char_indices()for byte offsets and slice with those.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
start | usize | |
end | usize |
Returns: String
slice_copy : (String) fn(self : String, r : Range(usize)) -> Stringslice_copy_inclusive : (String) fn(self : String, r : RangeInclusive(usize)) -> StringInclusive-range companion (s(a..=b)) — BYTE offsets, r.end included.
Because r.end is the LAST byte kept, it must be the last byte of a
rune for r.end + 1 to land on a boundary; otherwise this panics like
substring.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
r | RangeInclusive(usize) |
Returns: String
_index_of_impl : (String) fn(self : String, substr : String, from_index : usize) -> Option(usize)Byte offset of the first occurrence of substr at or after from_index.
BYTE basis, in AND out (plans/archive/STD_API_AUDIT_D4_PLAN.md D4 PR 3 —
both were rune indices before the flip). from_index is a byte offset;
the returned index is the byte offset the match starts at, so it can be
fed straight back into substring.
from_index needs no boundary check and gets none: UTF-8 is
self-synchronizing, so a valid-UTF-8 needle can never match starting at a
continuation byte. Starting the scan mid-rune therefore cannot invent a
match, and for a NON-EMPTY needle every index this returns is a rune
boundary at or before len().
The empty needle is the one exception, and it is deliberate. It
matches everywhere, so index_of(``, i) answers .Some(i) verbatim —
including an i inside a rune and an i past len() (JavaScript's
indexOf("") clamps to the length; this does not, and neither did the
pre-D4 rune-indexed version). An offset past the end is harmless
downstream because substring clamps, but a MID-RUNE one is not:
substring panics there. Callers that feed a search result straight back
into a slice and can be handed an empty needle should go through
try_substring, or snap with floor_char_boundary.
Not called directly — go through index_of.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
substr | String | |
from_index | usize | default: 0 |
Returns: Option(usize)
_contains_impl : (String) fn(self : String, substr : String, from_index : usize) -> boolPrivate: is substr present at or after BYTE offset from_index?
BYTE basis for from_index (plans/archive/STD_API_AUDIT_D4_PLAN.md D4
PR 3 — it was a rune index before the flip). Not called directly — go
through contains.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
substr | String | |
from_index | usize | default: 0 |
Returns: bool
_split_impl : (String) fn(self : String, separator : String) -> ArrayList(String)_last_index_of_impl : (String) fn(self : String, substr : String, from_index : usize) -> Option(usize)Byte offset of the LAST occurrence of substr starting at or before
from_index.
BYTE basis, in AND out (plans/archive/STD_API_AUDIT_D4_PLAN.md D4 PR 3 —
both were rune indices before the flip). from_index is the highest byte
offset a match is allowed to START at; the default usize.MAX means
"anywhere". The result is the byte offset of the match, and for a
non-empty needle it is always a rune boundary.
The empty needle answers len() regardless of from_index (Rust's
rfind("") shape), so it is the one case where the result can exceed the
cap the caller asked for. That is the pre-D4 behaviour carried over
unchanged — only the unit changed, from a rune count to a byte count.
Not called directly — go through last_index_of.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
substr | String | |
from_index | usize | default: -1 |
Returns: Option(usize)
_has_prefix : (String) fn(self : String, prefix : String, position : usize) -> boolPrivate: does this string have prefix starting at BYTE offset
position?
BYTE basis (plans/archive/STD_API_AUDIT_D4_PLAN.md D4 PR 3). Before the
flip position was walked rune-by-rune — and walked WRONG: the counter
advanced on a lead byte while the loop also stepped one byte, so
"你好".starts_with("好", 1) stopped at byte 1, in the middle of 你.
That is §1.3(a) of the plan, and byte indexing removes the walk that
caused it rather than repairing it.
position is never boundary-checked: a valid-UTF-8 prefix cannot match
starting at a continuation byte, so a mid-rune position simply answers
false. An empty prefix is present anywhere, including past the end.
The UTF-8-aware byte-compare reused by the Pattern impls behind the
generic starts_with<P : Pattern> (see
plans/backlog/OVERLOADING_REDESIGN.md §4). Not called directly — go
through starts_with.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
prefix | String | |
position | usize | default: 0 |
Returns: bool
_ends_with_impl : (String) fn(self : String, suffix : String, end_position : usize) -> boolPrivate: does the first end_position BYTES of this string end with
suffix?
BYTE basis (plans/archive/STD_API_AUDIT_D4_PLAN.md D4 PR 3 —
end_position was a rune count before the flip). The default
usize.MAX means "the whole string"; anything past len() clamps to it.
Like _has_prefix, a mid-rune end_position needs no rejection: a
valid-UTF-8 suffix cannot end there, so the answer is simply false.
Not called directly — go through ends_with.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
suffix | String | |
end_position | usize | default: -1 |
Returns: bool
to_uppercase : (String) fn(self : String) -> StringUppercase using the full Unicode 15.1 case mapping (all scripts, plus the
one-to-many expansions such as ß → SS and fi → FI). Locale-independent
(never consults the C locale). Context-sensitive rules (Greek final sigma,
Turkish dotted i) are not applied — the mapping is per code point, like
Go's strings.ToUpper. ASCII input keeps a byte-wise fast path.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: String
to_lowercase : (String) fn(self : String) -> Stringto_ascii_uppercase : (String) fn(self : String) -> Stringto_ascii_lowercase : (String) fn(self : String) -> String_is_whitespace_byte : (String) fn(byte : u8) -> boolHelper to check if a byte is ASCII whitespace Space (0x20), Tab (0x09), Newline (0x0A), Carriage Return (0x0D), Form Feed (0x0C), Vertical Tab (0x0B)
Parameters
| Name | Type | Notes |
|---|---|---|
byte | u8 |
Returns: bool
trim : (String) fn(self : String) -> Stringtrim_start : (String) fn(self : String) -> Stringtrim_end : (String) fn(self : String) -> String+ : (String) fn(self : String, other : String) -> String== : (String) fn(self : String, other : String) -> bool!= : (String) fn(self : String, other : String) -> bool== : (String) fn(self : String, other : str) -> bool!= : (String) fn(self : String, other : str) -> bool< : (String) fn(lhs : String, rhs : String) -> bool<= : (String) fn(lhs : String, rhs : String) -> bool> : (String) fn(lhs : String, rhs : String) -> bool>= : (String) fn(lhs : String, rhs : String) -> boolcmp : (String) fn(lhs : String, rhs : String) -> Orderingis_prefix_of : (String) fn(self : String, haystack : String, position : usize) -> boolis_suffix_of : (String) fn(self : String, haystack : String, end_position : usize) -> boolis_contained_in : (String) fn(self : String, haystack : String, from_index : usize) -> boolindex_in : (String) fn(self : String, haystack : String, from_index : usize) -> Option(usize)last_index_in : (String) fn(self : String, haystack : String, from_index : usize) -> Option(usize)length_in : (String) fn(self : String, haystack : String, at : usize) -> usizeNumber of BYTES the match STARTING EXACTLY at byte offset at occupies
— 0 when no match starts there. replace, replace_all, split_once
and strip_prefix cut the haystack by it; a zero-width pattern (empty
string, empty-matching regex) legitimately answers 0.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
haystack | String | |
at | usize |
Returns: usize
split_of : (String) fn(self : String, haystack : String) -> ArrayList(String)Every piece of haystack between occurrences of this pattern, in order.
The only Pattern method with no offset argument — it always covers the
whole haystack — and the only one an implementation may give a shape of
its own: String / str treat an EMPTY pattern as "split into runes"
(see String.split), which no offset-based method can express.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
haystack | String |
starts_with : (String) fn(generic(P) self : String, prefix : P : (Pattern), position : usize) -> boolends_with : (String) fn(generic(P) self : String, suffix : P : (Pattern), end_position : usize) -> boolcontains : (String) fn(generic(P) self : String, substr : P : (Pattern), from_index : usize) -> boolindex_of : (String) fn(generic(P) self : String, substr : P : (Pattern), from_index : usize) -> Option(usize)last_index_of : (String) fn(generic(P) self : String, substr : P : (Pattern), from_index : usize) -> Option(usize)split_whitespace : (String) fn(self : String) -> ArrayList(String)splitn : (String) fn(generic(P) self : String, n : usize, separator : P : (Pattern)) -> ArrayList(String)is_ascii : (String) fn(self : String) -> boolWhether every byte is ASCII (< 0x80) — Rust's is_ascii.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: bool
eq_ignore_ascii_case : (String) fn(self : String, other : String) -> booltruncate : (String) fn(self : String, new_len : usize) -> unitShorten to new_len BYTES, panicking if that is not a char boundary —
Rust's truncate. A longer new_len is a no-op.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
new_len | usize |
Returns: unit
trim_start_matches : (String) fn(generic(P) self : String, pat : P : (Pattern)) -> Stringself with every leading occurrence of pat removed — Rust's
trim_start_matches. Repeats, so "aaab".trim_start_matches("a") is
"b", unlike the single-shot strip_prefix.
A ZERO-WIDTH pattern (the empty string, a regex matching empty) strips nothing and terminates rather than spinning.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
pat | P : (Pattern) |
Returns: String
trim_end_matches : (String) fn(generic(P) self : String, pat : P : (Pattern)) -> Stringtrim_matches : (String) fn(generic(P) self : String, pat : P : (Pattern)) -> Stringsplit : (String) fn(generic(P) self : String, separator : P : (Pattern)) -> ArrayList(String)self cut at every occurrence of separator — Rust's str::split,
but EAGER: the pieces come back as an ArrayList(String), not a lazy
iterator.
separator is any Pattern (a str, a String, a single rune, or a
compiled Regex). Separators are consumed, so n matches yield n + 1
pieces, including empty ones at the ends; a separator that never matches
yields self alone, and splitting the empty string yields one empty
piece.
DIVERGENCE from Rust: an EMPTY separator means "split into runes"
(JavaScript's "abc".split("")), so "abc".split("") is
["a", "b", "c"] — not Rust's ["", "a", "b", "c", ""]. It is pinned to
the rune vocabulary on purpose: a byte-wise split would hand back
fragments that are not valid UTF-8 now that len() counts bytes.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
separator | P : (Pattern) |
rsplit : (String) fn(generic(P) self : String, separator : P : (Pattern)) -> ArrayList(String)split's pieces from the RIGHT — Rust's rsplit.
The pieces are the same ones split produces; only the ORDER is
reversed, so "a.b.c".rsplit(".") is ["c", "b", "a"]. (Rust's returns
a lazy iterator; Yo's split already returns the whole list, so this
reverses it.)
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
separator | P : (Pattern) |
insert_str : (String) fn(self : String, idx : usize, s : String) -> unitInsert s at BYTE index idx, shifting the rest right — Rust's
insert_str.
PANICS when idx is past the end or is not a char boundary, as Rust
does; len() is bytes, so an index into the middle of a multi-byte rune
would otherwise produce invalid UTF-8.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
idx | usize | |
s | String |
Returns: unit
insert : (String) fn(self : String, idx : usize, r : rune) -> unitInsert one rune at BYTE index idx — Rust's insert. Same panics as
insert_str.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
idx | usize | |
r | rune |
Returns: unit
remove : (String) fn(self : String, idx : usize) -> runeRemove and return the rune STARTING at byte index idx — Rust's
remove.
PANICS when idx is out of bounds or not a char boundary.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
idx | usize |
Returns: rune
pop : (String) fn(self : String) -> Option(rune)split_once : (String) fn(generic(P) self : String, separator : P : (Pattern)) -> Option(Tuple(0 : String, 1 : String))Split at the FIRST occurrence of separator: .Some((before; after))
with the separator itself removed, or .None when it never occurs.
Rust's str::split_once. A zero-width separator (empty string pattern,
regex matching empty) splits before the first rune.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
separator | P : (Pattern) |
strip_prefix : (String) fn(generic(P) self : String, prefix : P : (Pattern)) -> Option(String)strip_suffix : (String) fn(generic(P) self : String, suffix : P : (Pattern)) -> Option(String)_replace_scan : (String) fn(generic(P) self : String, search_value : P : (Pattern), new_value : String, limit : usize, bounded : bool) -> StringShared left-to-right scanner behind replace, replacen and
replace_first. When bounded is true it stops after limit
replacements and copies the rest of the string verbatim; limit == 0
with bounded replaces nothing.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
search_value | P : (Pattern) | |
new_value | String | |
limit | usize | |
bounded | bool |
Returns: String
replace : (String) fn(generic(P) self : String, search_value : P : (Pattern), new_value : String) -> StringReplace EVERY occurrence of search_value with new_value (D10 —
Rust's str::replace).
search_value is any Pattern — a str, a String, a single rune, or
a compiled Regex. A zero-width match inserts new_value between every
pair of runes and at both ends — Rust's "abc".replace("", "-") == "-a-b-c-" — by stepping one rune past each zero-width match so the scan
always advances. Returns self unchanged when the pattern never matches.
NOTE this replaced only the FIRST occurrence before D10. Use replacen
for a bounded count.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
search_value | P : (Pattern) | |
new_value | String |
Returns: String
replacen : (String) fn(generic(P) self : String, search_value : P : (Pattern), new_value : String, count : usize) -> StringReplace the first count occurrences of search_value with new_value,
leaving any later ones alone — Rust's str::replacen.
replacen(p, v, usize(1)) is the pre-D10 meaning of replace.
count == 0 returns self unchanged.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
search_value | P : (Pattern) | |
new_value | String | |
count | usize |
Returns: String
replace_first : (String) fn(generic(P) self : String, search_value : P : (Pattern), new_value : String) -> Stringreplace_all : (String) fn(generic(P) self : String, search_value : P : (Pattern), new_value : String) -> Stringhash : (String) fn(generic(H) self : String, hasher : H : (Hasher)) -> unitchars : (String) fn(self : String) -> StringCharsReturns a rune iterator over the string's Unicode characters
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: StringChars
bytes : (String) fn(self : String) -> StringBytesReturns a byte iterator over the string's raw UTF-8 bytes
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: StringBytes
into_iter : (String) fn(self : String) -> StringCharsConsume the string and return a rune iterator (default iteration)
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: StringChars
char_indices : (String) fn(self : String) -> StringCharIndicesIterate (byte_offset, rune) pairs — Rust's char_indices().
_0 is the byte offset the rune starts at, _1 is the rune. This is
the replacement for the while(i < s.len()) { s.at(i) } shape, which
now visits continuation bytes and hands back .None at each of them.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: StringCharIndices
floor_char_boundary : (String) fn(self : String, index : usize) -> usizeThe largest byte offset <= index that sits on a rune boundary.
index is clamped to len() first, so the answer is always a
boundary of THIS string. Pair it with ceil_char_boundary to widen or
narrow a byte range onto boundaries before slicing.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
index | usize |
Returns: usize
ceil_char_boundary : (String) fn(self : String, index : usize) -> usizeThe smallest byte offset >= index that sits on a rune boundary.
index at or past len() clamps to len(), which is a boundary, so
this always terminates on a valid one.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
index | usize |
Returns: usize
try_substring : (String) fn(self : String, start : usize, end : usize) -> Option(String)Byte-range slice that REFUSES a bad range instead of guessing —
Rust's s.get(start..end).
Same BYTE basis as substring, but REFUSING where substring clamps or
panics: .None is returned for each of the three ranges a byte slice
cannot honour — start > end, end past len(), or an endpoint inside
a rune (which would produce invalid UTF-8). An empty but valid range
yields .Some of the empty string.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
start | usize | |
end | usize |
lines : (String) fn(self : String) -> StringLinesReturns a line iterator over the string.
Each call to next() yields the next line (without the trailing \n).
Example
s := `hello\nworld`;
iter := s.lines();
assert(iter.next() == .Some(`hello`), "first line");
assert(iter.next() == .Some(`world`), "second line");
assert(iter.next() == .None, "done");
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: StringLines
repeat : (String) fn(self : String, n : usize) -> Stringjoin : (String) fn(self : String, items : ArrayList(String)) -> StringJoin an ArrayList(String) with this string as separator.
Returns an empty string when items is empty.
Example
items := ArrayList(String).new();
items.push(`a`);
items.push(`b`);
items.push(`c`);
result := `, `.join(items);
assert(result == `a, b, c`, "join");
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
items | ArrayList(String) |
Returns: String
parse_bool : (String) fn(self : String) -> Option(bool)Parse the string as a boolean. Returns .Some(true) for "true", .Some(false) for "false", .None for anything else.
DEPRECATED (D12), kept for one release: use s.parse(bool), which reports
WHY the parse failed instead of collapsing every reason into .None.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: Option(bool)
parse_f64 : (String) fn(self : String) -> Option(f64)Parse an f64 — Rust's f64::from_str grammar: optional sign, digits
with optional fraction and exponent, or inf/infinity/nan
(case-insensitive). Leading/trailing whitespace and hex floats are NOT
accepted. .None when the string is not a valid number.
DEPRECATED (D12), kept for one release: use s.parse(f64), which reports
WHY the parse failed instead of collapsing every reason into .None.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: Option(f64)
parse_i64_radix : (String) fn(self : String, radix : u32) -> Option(i64)Parse an i64 in the given radix (2..=36, digits 0-9/a-z/A-Z) —
Rust's i64::from_str_radix. An optional leading +/- is allowed;
_ is not. .None on an empty digit run, any non-digit, a bad radix,
or overflow.
DEPRECATED (D12), kept for one release: use s.parse(i64), which reports
WHY the parse failed instead of collapsing every reason into .None.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
radix | u32 |
Returns: Option(i64)
parse_u64_radix : (String) fn(self : String, radix : u32) -> Option(u64)Parse a u64 in the given radix (2..=36) — Rust's
u64::from_str_radix. An optional leading + is allowed; - is not.
.None on any non-digit, a bad radix, or overflow.
DEPRECATED (D12), kept for one release: use s.parse(u64), which reports
WHY the parse failed instead of collapsing every reason into .None.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
radix | u32 |
Returns: Option(u64)
parse_i32 : (String) fn(self : String) -> Option(i32)Parse the string as a signed 32-bit integer — Rust's i32::from_str.
An optional leading +/- is allowed. .None on an empty digit run,
any non-digit, or a value outside i32.
DEPRECATED (D12), kept for one release: use s.parse(i32), which reports
WHY the parse failed instead of collapsing every reason into .None.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: Option(i32)
parse_i64 : (String) fn(self : String) -> Option(i64)Parse the string as a signed 64-bit integer — Rust's i64::from_str.
An optional leading +/- is allowed. .None on an empty digit run,
any non-digit, or overflow (i64.MIN itself is accepted).
DEPRECATED (D12), kept for one release: use s.parse(i64), which reports
WHY the parse failed instead of collapsing every reason into .None.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: Option(i64)
parse_u32 : (String) fn(self : String) -> Option(u32)Parse the string as an unsigned 32-bit integer — Rust's u32::from_str.
An optional leading + is allowed, - is not. .None on an empty digit
run, any non-digit, or a value outside u32.
DEPRECATED (D12), kept for one release: use s.parse(u32), which reports
WHY the parse failed instead of collapsing every reason into .None.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: Option(u32)
parse_u64 : (String) fn(self : String) -> Option(u64)Parse the string as an unsigned 64-bit integer — Rust's u64::from_str.
An optional leading + is allowed, - is not. .None on an empty digit
run, any non-digit, or overflow.
DEPRECATED (D12), kept for one release: use s.parse(u64), which reports
WHY the parse failed instead of collapsing every reason into .None.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String |
Returns: Option(u64)
parse : (String) fn(self : String, T : Type) -> Result(T : (FromString), Err)Parse this string as a T — Rust's str::parse::<T>() (D12).
match(`42`.parse(i32), .Ok(v) => v, .Err(_) => i32(0));
The error is T's own, so a caller can tell an empty string from garbage
from an out-of-range value. T is written out because it cannot be
inferred from the arguments — only from the result, which Yo does not do.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
T | Type | comptime |
Returns: Result(T : (FromString), Err)
parse_i64_radix_res : (String) fn(self : String, radix : u32) -> Result(i64, ParseIntError)Parse a signed integer in radix (2..=36) — Rust's i64::from_str_radix,
reporting WHY it failed.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
radix | u32 |
Returns: Result(i64, ParseIntError)
parse_u64_radix_res : (String) fn(self : String, radix : u32) -> Result(u64, ParseIntError)Parse an unsigned integer in radix (2..=36) — Rust's
u64::from_str_radix, reporting WHY it failed.
Parameters
| Name | Type | Notes |
|---|---|---|
self | String | |
radix | u32 |
Returns: Result(u64, ParseIntError)
index : (String) fn(self : String, idx : usize) -> *(u8)default : (String) fn() -> StringThe default value of the type.
Returns: String
clone : (String) fn(self : String) -> Stringfrom_iter_new : (String) fn() -> StringThe empty collection collect starts from.
Returns: String
from_iter_add : (String) fn(acc : String, item : String) -> Stringto_string : (String) fn(self : String) -> Stringdebug_string : (String) fn(self : String) -> Stringsource : (String) fn(self : String) -> Option(dyn( + ToString))to_json : (String) fn(self : String) -> JsonValueString operation error variants.
Variants
| Variant | Fields | Description |
|---|---|---|
InvalidUtf8 | cause: Utf8Error | The input bytes are not valid UTF-8. |
IndexOutOfBounds | index: usize, length: usize | The index is out of bounds for the string's byte length. |
Rune iterator for String — yields decoded runes. Produced by chars()
and by into_iter(), and double-ended (next_back), so .rev() works.
Built on std/encoding/utf8, and inherits its malformed-input behaviour:
iteration STOPS at the first byte sequence that will not decode rather
than substituting a replacement character.
Fields
| Name | Type | Description |
|---|---|---|
_string | String | |
_byte_index | usize | |
_end | usize | Exclusive BACK cursor — see |
impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> B)) -> IterMap(I : (Iterator), B, F : (Fn(A) -> B))filter : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterFilter(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterFilter(I : (Iterator), F : (Fn(A) -> bool))
take : fn(generic(A) self : I : (Iterator), n : usize) -> IterTake(I : (Iterator))skip : fn(generic(A) self : I : (Iterator), n : usize) -> IterSkip(I : (Iterator))enumerate : fn(generic(A) self : I : (Iterator)) -> IterEnumerate(I : (Iterator))zip : fn(generic(A, J, B) self : I : (Iterator), other : J : (Iterator)) -> IterZip(I : (Iterator), J : (Iterator))fold : fn(generic(A, Acc, F) self : I : (Iterator), init : Acc, f : F : (Fn(Acc, A) -> Acc)) -> Accfor_each : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> unit)) -> unitcount : fn(generic(A) self : I : (Iterator)) -> usizeany : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> boolall : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> boolfind : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(A)position : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(usize)last : fn(generic(A) self : I : (Iterator)) -> Option(A)nth : fn(generic(A) self : I : (Iterator), n : usize) -> Option(A)sum : fn(generic(A) self : I : (Iterator)) -> A : ((Output : Type, + : fn(lhs : Self, rhs : A) -> Output) + Default)min : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) |
Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))
max : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) |
Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))
chain : fn(generic(A, J) self : I : (Iterator), other : J : (Iterator)) -> IterChain(I : (Iterator), J : (Iterator))take_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))
skip_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))
filter_map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> Option(B))) -> IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> Option(B)) |
Returns: IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))
peekable : fn(generic(A) self : I : (Iterator)) -> IterPeekable(I : (Iterator), A)collect : fn(self : I : (Iterator), C : Type) -> C : (FromIterator)impl(generic(I : Type), where(I <: DoubleEndedIterator), I : (DoubleEndedIterator))
rev : fn(self : I : (DoubleEndedIterator)) -> IterRev(I : (DoubleEndedIterator))Methods
next : (StringChars) fn(self : StringChars) -> Option(rune)Advance the iterator and return the next value, or None when exhausted.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringChars |
Returns: Option(rune)
next_back : (StringChars) fn(self : StringChars) -> Option(rune)Advance the iterator from the back and return the previous value, or
None when the two ends have met.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringChars |
Returns: Option(rune)
(byte_offset, rune) iterator for String — yields each rune together with
the byte offset it starts at. Used by char_indices().
Walks in lockstep with StringChars: same runes, same stopping point on
malformed input. The offsets it yields are exactly the indices
is_char_boundary answers true for (on well-formed UTF-8).
Fields
| Name | Type | Description |
|---|---|---|
_string | String | |
_byte_index | usize | |
_end | usize | Exclusive BACK cursor — see |
impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> B)) -> IterMap(I : (Iterator), B, F : (Fn(A) -> B))filter : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterFilter(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterFilter(I : (Iterator), F : (Fn(A) -> bool))
take : fn(generic(A) self : I : (Iterator), n : usize) -> IterTake(I : (Iterator))skip : fn(generic(A) self : I : (Iterator), n : usize) -> IterSkip(I : (Iterator))enumerate : fn(generic(A) self : I : (Iterator)) -> IterEnumerate(I : (Iterator))zip : fn(generic(A, J, B) self : I : (Iterator), other : J : (Iterator)) -> IterZip(I : (Iterator), J : (Iterator))fold : fn(generic(A, Acc, F) self : I : (Iterator), init : Acc, f : F : (Fn(Acc, A) -> Acc)) -> Accfor_each : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> unit)) -> unitcount : fn(generic(A) self : I : (Iterator)) -> usizeany : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> boolall : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> boolfind : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(A)position : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(usize)last : fn(generic(A) self : I : (Iterator)) -> Option(A)nth : fn(generic(A) self : I : (Iterator), n : usize) -> Option(A)sum : fn(generic(A) self : I : (Iterator)) -> A : ((Output : Type, + : fn(lhs : Self, rhs : A) -> Output) + Default)min : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) |
Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))
max : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) |
Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))
chain : fn(generic(A, J) self : I : (Iterator), other : J : (Iterator)) -> IterChain(I : (Iterator), J : (Iterator))take_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))
skip_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))
filter_map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> Option(B))) -> IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> Option(B)) |
Returns: IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))
peekable : fn(generic(A) self : I : (Iterator)) -> IterPeekable(I : (Iterator), A)collect : fn(self : I : (Iterator), C : Type) -> C : (FromIterator)impl(generic(I : Type), where(I <: DoubleEndedIterator), I : (DoubleEndedIterator))
rev : fn(self : I : (DoubleEndedIterator)) -> IterRev(I : (DoubleEndedIterator))Methods
next : (StringCharIndices) fn(self : StringCharIndices) -> Option(IterPair(usize, rune))Advance the iterator and return the next value, or None when exhausted.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringCharIndices |
next_back : (StringCharIndices) fn(self : StringCharIndices) -> Option(IterPair(usize, rune))Advance the iterator from the back and return the previous value, or
None when the two ends have met.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringCharIndices |
Byte iterator for String — yields raw UTF-8 bytes.
Used by bytes().
Fields
| Name | Type | Description |
|---|---|---|
_string | String | |
_index | usize | |
_end | usize | Exclusive BACK cursor — see |
impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> B)) -> IterMap(I : (Iterator), B, F : (Fn(A) -> B))filter : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterFilter(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterFilter(I : (Iterator), F : (Fn(A) -> bool))
take : fn(generic(A) self : I : (Iterator), n : usize) -> IterTake(I : (Iterator))skip : fn(generic(A) self : I : (Iterator), n : usize) -> IterSkip(I : (Iterator))enumerate : fn(generic(A) self : I : (Iterator)) -> IterEnumerate(I : (Iterator))zip : fn(generic(A, J, B) self : I : (Iterator), other : J : (Iterator)) -> IterZip(I : (Iterator), J : (Iterator))fold : fn(generic(A, Acc, F) self : I : (Iterator), init : Acc, f : F : (Fn(Acc, A) -> Acc)) -> Accfor_each : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> unit)) -> unitcount : fn(generic(A) self : I : (Iterator)) -> usizeany : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> boolall : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> boolfind : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(A)position : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(usize)last : fn(generic(A) self : I : (Iterator)) -> Option(A)nth : fn(generic(A) self : I : (Iterator), n : usize) -> Option(A)sum : fn(generic(A) self : I : (Iterator)) -> A : ((Output : Type, + : fn(lhs : Self, rhs : A) -> Output) + Default)min : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) |
Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))
max : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) |
Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))
chain : fn(generic(A, J) self : I : (Iterator), other : J : (Iterator)) -> IterChain(I : (Iterator), J : (Iterator))take_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))
skip_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))
filter_map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> Option(B))) -> IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> Option(B)) |
Returns: IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))
peekable : fn(generic(A) self : I : (Iterator)) -> IterPeekable(I : (Iterator), A)collect : fn(self : I : (Iterator), C : Type) -> C : (FromIterator)impl(generic(I : Type), where(I <: DoubleEndedIterator), I : (DoubleEndedIterator))
rev : fn(self : I : (DoubleEndedIterator)) -> IterRev(I : (DoubleEndedIterator))Methods
next : (StringBytes) fn(self : StringBytes) -> Option(u8)Advance the iterator and return the next value, or None when exhausted.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBytes |
Returns: Option(u8)
next_back : (StringBytes) fn(self : StringBytes) -> Option(u8)Advance the iterator from the back and return the previous value, or
None when the two ends have met.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBytes |
Returns: Option(u8)
Line iterator for String — yields one line at a time (split on \n).
The trailing newline is not included in each yielded line.
Used by lines().
Fields
| Name | Type | Description |
|---|---|---|
_string | String | |
_byte_index | usize | |
_end | usize | Exclusive BACK cursor — see |
impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
impl(generic(I : Type), where(I <: Iterator), I : (Iterator))
map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> B)) -> IterMap(I : (Iterator), B, F : (Fn(A) -> B))filter : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterFilter(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterFilter(I : (Iterator), F : (Fn(A) -> bool))
take : fn(generic(A) self : I : (Iterator), n : usize) -> IterTake(I : (Iterator))skip : fn(generic(A) self : I : (Iterator), n : usize) -> IterSkip(I : (Iterator))enumerate : fn(generic(A) self : I : (Iterator)) -> IterEnumerate(I : (Iterator))zip : fn(generic(A, J, B) self : I : (Iterator), other : J : (Iterator)) -> IterZip(I : (Iterator), J : (Iterator))fold : fn(generic(A, Acc, F) self : I : (Iterator), init : Acc, f : F : (Fn(Acc, A) -> Acc)) -> Accfor_each : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> unit)) -> unitcount : fn(generic(A) self : I : (Iterator)) -> usizeany : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> boolall : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> boolfind : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(A)position : fn(generic(A, F) self : I : (Iterator), pred : F : (Fn(A) -> bool)) -> Option(usize)last : fn(generic(A) self : I : (Iterator)) -> Option(A)nth : fn(generic(A) self : I : (Iterator), n : usize) -> Option(A)sum : fn(generic(A) self : I : (Iterator)) -> A : ((Output : Type, + : fn(lhs : Self, rhs : A) -> Output) + Default)min : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) |
Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))
max : fn(generic(A) self : I : (Iterator)) -> Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) |
Returns: Option(A : ((< : fn(lhs : Self : ((== : fn(lhs : Self, rhs : A) -> bool, != : fn(lhs : Self, rhs : A) -> bool)), rhs : A) -> bool, <= : fn(lhs : Self, rhs : A) -> bool, > : fn(lhs : Self, rhs : A) -> bool, >= : fn(lhs : Self, rhs : A) -> bool, cmp : fn(lhs : Self, rhs : A) -> Ordering)))
chain : fn(generic(A, J) self : I : (Iterator), other : J : (Iterator)) -> IterChain(I : (Iterator), J : (Iterator))take_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterTakeWhile(I : (Iterator), F : (Fn(A) -> bool))
skip_while : fn(generic(A, F) self : I : (Iterator), f : F : (Fn(A) -> bool)) -> IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> bool) |
Returns: IterSkipWhile(I : (Iterator), F : (Fn(A) -> bool))
filter_map : fn(generic(A, B, F) self : I : (Iterator), f : F : (Fn(A) -> Option(B))) -> IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))Parameters
| Name | Type | Notes |
|---|---|---|
self | I : (Iterator) | |
f | F : (Fn(A) -> Option(B)) |
Returns: IterFilterMap(I : (Iterator), B, F : (Fn(A) -> Option(B)))
peekable : fn(generic(A) self : I : (Iterator)) -> IterPeekable(I : (Iterator), A)collect : fn(self : I : (Iterator), C : Type) -> C : (FromIterator)impl(generic(I : Type), where(I <: DoubleEndedIterator), I : (DoubleEndedIterator))
rev : fn(self : I : (DoubleEndedIterator)) -> IterRev(I : (DoubleEndedIterator))Methods
next : (StringLines) fn(self : StringLines) -> Option(String)Advance the iterator and return the next value, or None when exhausted.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringLines |
next_back : (StringLines) fn(self : StringLines) -> Option(String)Advance the iterator from the back and return the previous value, or
None when the two ends have met.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringLines |
Magnitude of the digit run starting at start (sign already consumed),
with overflow checks. The whole remainder must be digits.
Why a string could not be parsed as an integer — Rust's ParseIntError
(D12). The older parse_*() -> Option(T) methods collapsed all of these
into .None, so a caller could not tell a missing field from a malformed
one from one that simply did not fit.
Variants
| Variant | Fields | Description |
|---|---|---|
Empty | The string was empty. | |
InvalidDigit | A byte was not a digit in the requested radix. | |
PosOverflow | The value is larger than the type's maximum. | |
NegOverflow | The value is smaller than the type's minimum. | |
InvalidRadix | The radix passed to a |
Trait Implementations
impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> StringRender self under spec. An unrecognised spec degrades to the plain
to_string() rendering rather than failing.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Self | |
spec | str |
Returns: String
Methods
to_string : (ParseIntError) fn(self : ParseIntError) -> Stringsource : (ParseIntError) fn(self : ParseIntError) -> Option(dyn( + ToString))Why a string could not be parsed as a float — Rust's ParseFloatError.
Variants
| Variant | Fields | Description |
|---|---|---|
Empty | The string was empty. | |
Invalid | The string was anything other than |
Trait Implementations
impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> StringRender self under spec. An unrecognised spec degrades to the plain
to_string() rendering rather than failing.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Self | |
spec | str |
Returns: String
Methods
to_string : (ParseFloatError) fn(self : ParseFloatError) -> Stringsource : (ParseFloatError) fn(self : ParseFloatError) -> Option(dyn( + ToString))Why a string could not be parsed as a bool — Rust's ParseBoolError.
Only "true" and "false" are accepted.
Variants
| Variant | Fields | Description |
|---|---|---|
Invalid | The string was anything other than |
Trait Implementations
impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> StringRender self under spec. An unrecognised spec degrades to the plain
to_string() rendering rather than failing.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Self | |
spec | str |
Returns: String
Methods
to_string : (ParseBoolError) fn(self : ParseBoolError) -> Stringsource : (ParseBoolError) fn(self : ParseBoolError) -> Option(dyn( + ToString))Where the text sits inside a padded field — the argument to
write_padded, and the same three cases FormatSpec parses from
< / > / ^.
It lives here rather than in std/fmt because write_padded does, and
std/fmt already depends on std/string; the other direction would be a
cycle. std/fmt re-exports it, so importing it from std/fmt works too.
Variants
| Variant | Fields | Description |
|---|---|---|
Left | ||
Right | ||
Center |
Mutable buffer for building a String incrementally.
Use StringBuilder when you need to construct a string from many parts,
appending bytes or strings in a loop, before converting to an immutable
String with to_string().
Example
sb := StringBuilder.new();
sb.write_str("Hello");
sb.write_str(", ");
sb.write_string(`world`);
sb.write_byte(u8(33)); // '!'
result := sb.to_string();
assert(result == `Hello, world!`, "built string");
Fields
| Name | Type | Description |
|---|---|---|
_buf | ArrayList(u8) |
Methods
new : (StringBuilder) fn() -> StringBuilderCreate a new, empty StringBuilder.
Returns: StringBuilder
with_capacity : (StringBuilder) fn(capacity : usize) -> StringBuilderCreate a StringBuilder pre-allocated for capacity bytes.
Parameters
| Name | Type | Notes |
|---|---|---|
capacity | usize |
Returns: StringBuilder
len : (StringBuilder) fn(self : StringBuilder) -> usizeReturns the current number of bytes in the buffer.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder |
Returns: usize
is_empty : (StringBuilder) fn(self : StringBuilder) -> boolwrite_str : (StringBuilder) fn(self : StringBuilder, s : str) -> unitAppend a str (raw byte slice) to the buffer.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder | |
s | str |
Returns: unit
write_string : (StringBuilder) fn(self : StringBuilder, s : String) -> unitwrite_byte : (StringBuilder) fn(self : StringBuilder, b : u8) -> unitwrite_rune : (StringBuilder) fn(self : StringBuilder, r : rune) -> unitAppend a single Unicode code point, encoded as UTF-8.
Example
sb := StringBuilder.new();
sb.write_rune(rune(0x1F600)); // 😀
sb.write_rune(rune(0x41)); // 'A'
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder | |
r | rune |
Returns: unit
write_line : (StringBuilder) fn(self : StringBuilder, s : String) -> unitAppend a String followed by a newline byte (\n).
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder | |
s | String |
Returns: unit
to_string : (StringBuilder) fn(self : StringBuilder) -> StringDetach the accumulated bytes as a String, leaving the builder EMPTY and
still usable.
It does not copy and it does not consume the builder: the receiver is a
reference, and it starts over with a fresh buffer, so building an N-byte
string costs O(N) once. The returned String is therefore independent —
a later write_* on the same builder cannot mutate a string already
handed to a caller.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder |
Returns: String
write_hex : (StringBuilder) fn(self : StringBuilder, n : u64) -> unitAppend an unsigned 64-bit integer in lowercase hexadecimal.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder | |
n | u64 |
Returns: unit
write_f64 : (StringBuilder) fn(self : StringBuilder, n : f64, precision : i32) -> unitAppend n with exactly precision decimal places.
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder | |
n | f64 | |
precision | i32 |
Returns: unit
write_padded : (StringBuilder) fn(self : StringBuilder, s : str, width : usize, pad : rune, align : Alignment) -> unitAppend s padded to width RUNES with pad, aligned per align.
A s already at or over the width is written unpadded.
Width is a RUNE count, matching FormatSpec's {:width$} and Rust's.
It used to be a BYTE count here, so write_padded("héllo", 8, ' ', .Left)
emitted two spaces instead of three and the column did not line up — the
two width bases in one module disagreed
(issues/fixed/write-padded-counted-bytes-where-formatspec-counts-runes.md).
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder | |
s | str | |
width | usize | |
pad | rune | |
align | Alignment |
Returns: unit
clear : (StringBuilder) fn(self : StringBuilder) -> unitEmpty the builder.
This RELEASES the buffer rather than retaining its capacity — unlike
Rust's String::clear and unlike ArrayList.clear, both of which keep the
allocation for reuse. A builder cleared in a loop therefore reallocates
from zero on every pass; when that matters, keep a fresh builder per
iteration instead (it costs the same) or hand the bytes off with
to_string(), which detaches for the same price.
(issues/stddoc-str-string-builder-clear-drops-capacity.md)
Parameters
| Name | Type | Notes |
|---|---|---|
self | StringBuilder |
Returns: unit
default : (StringBuilder) fn() -> StringBuilderThe default value of the type.
Returns: StringBuilder
Traits / Modules
Methods
is_prefix_of : fn(self : Self, haystack : String, position : usize) -> boolis_suffix_of : fn(self : Self, haystack : String, end_position : usize) -> boolis_contained_in : fn(self : Self, haystack : String, from_index : usize) -> boolindex_in : fn(self : Self, haystack : String, from_index : usize) -> Option(usize)last_index_in : fn(self : Self, haystack : String, from_index : usize) -> Option(usize)length_in : fn(self : Self, haystack : String, at : usize) -> usizesplit_of : fn(self : Self, haystack : String) -> ArrayList(String)