Str
Concatenates two strings together.
expect "ab".concat("cd") == "abcd"
expect "hello".concat("") == "hello"
expect "".concat("") == ""
Determines whether or not the first Str contains the second.
expect "foobarbaz".contains("bar")
expect !"apple".contains("orange")
expect "anything".contains("")
Return the Str with all whitespace removed from both the beginning as well as the end.
expect " Hello \n\n".trim() == "Hello"
trim_start : Str -> Str
Return the Str with all whitespace removed from the beginning.
expect " Hello \n\n".trim_start() == "Hello \n\n"
Return the Str with all whitespace removed from the end.
expect " Hello \n\n".trim_end() == " Hello"
caseless_ascii_equals : Str, Str -> Bool
Returns True if all the ASCII characters in both strings are the same,
ignoring differences in capitalization.
Non-ASCII characters must all be exactly the same,
including capitalization. For example:
expect "café".caseless_ascii_equals("CAFé")
expect !"café".caseless_ascii_equals("CAFÉ")
The first call returns True because all the ASCII characters are the same
when ignoring differences in capitalization, and the only non-ASCII character
(é) is the same in both strings. The second call returns False because
é and É are not ASCII characters, and they are different.
This function is useful for things like command-line flags and environment variable names where you know in advance that you're dealing with a string containing only ASCII characters. It has better performance than lowercasing operations which take Unicode into account.
That said, strings received from user input can always contain
non-ASCII Unicode characters, and lowercasing Unicode works
differently in different languages. For example, the string "I" lowercases to "i"
in English and to "ı" (a dotless i)
in Turkish. These rules can also change in each Unicode release,
so we have separate unicode package
for Unicode capitalization that can be upgraded independently from the language's builtins.
To convert a string's ASCII characters to uppercase or lowercase, you can use Str.with_ascii_uppercased or Str.with_ascii_lowercased.
with_ascii_lowercased : Str -> Str
Returns a version of the string with all ASCII characters lowercased. Non-ASCII characters are left unmodified. For example:
expect "CALFÉ".with_ascii_lowercased() == "calfÉ"
This function is useful for things like command-line flags and environment variable names where you know in advance that you're dealing with a string containing only ASCII characters. It has better performance than lowercasing operations which take Unicode into account.
That said, strings received from user input can always contain
non-ASCII Unicode characters, and lowercasing Unicode works
differently in different languages. For example, the string "I" lowercases to "i"
in English and to "ı" (a dotless i)
in Turkish. These rules can also change in each Unicode release,
so we have separate unicode package
for Unicode capitalization that can be upgraded independently from the language's builtins.
To do a case-insensitive comparison of the ASCII characters in a string, you can use Str.caseless_ascii_equals.
with_ascii_uppercased : Str -> Str
Returns a version of the string with all ASCII characters uppercased. Non-ASCII characters are left unmodified. For example:
expect "café".with_ascii_uppercased() == "CAFé"
This function is useful for things like command-line flags and environment variable names where you know in advance that you're dealing with a string containing only ASCII characters. It has better performance than uppercasing operations which take Unicode into account.
That said, strings received from user input can always contain
non-ASCII Unicode characters, and uppercasing Unicode
works differently in different languages.
For example, the string "i" uppercases to "I" in English and to "İ"
(a dotted I) in Turkish.
These rules can also change in each Unicode release,
so we have a separate unicode package for Unicode capitalization
that can be upgraded independently from the language's builtins.
To do a case-insensitive comparison of the ASCII characters in a string, you can use Str.caseless_ascii_equals.
starts_with : Str, Str -> Bool
Check if the given Str starts with a value.
expect "ABC".starts_with("A") == Bool.True
expect "ABC".starts_with("X") == Bool.False
Check if the given Str ends with a value.
expect "ABC".ends_with("C") == Bool.True
expect "ABC".ends_with("X") == Bool.False
Repeats a string the given number of times.
expect "z".repeat(3) == "zzz"
expect "na".repeat(8) == "nananananananana"
Returns "" when given "" for the string or 0 for the count.
expect "".repeat(10) == ""
expect "anything".repeat(0) == ""
with_prefix : Str, Str -> Str
Adds a prefix to the given Str.
expect "Awesome".with_prefix("Roc") == "RocAwesome"
drop_prefix : Str, Str -> Str
drop_suffix : Str, Str -> Str
count_utf8_bytes : Str -> U64
Gives the number of bytes in a Str value.
expect "Hello World".count_utf8_bytes() == 11
with_capacity : U64 -> Str
Returns a string of the specified capacity without any content.
This is like calling Str.reserve on an empty string. It's intended for building up a string incrementally, for example by calling Str.concat on it:
greeting = "Hello and welcome to Roc"
subject = "Awesome Programmer"
# Evaluates to "Hello and welcome to Roc, Awesome Programmer!"
# Note that string interpolation with "${greeting}, ${subject}!" would be preferred here,
# this is just a simple example to demonstrate `Str.with_capacity`.
hello_world =
Str.with_capacity(45)
.concat(greeting)
.concat(", ")
.concat(subject)
.concat("!")
When the final size is known up front, Str.with_capacity guarantees that
subsequent calls to Str.concat will not need to reallocate. Whether this
is faster than starting from "" depends on the system allocator: many
allocators can extend an existing allocation in place, making the difference
small or negligible. The benefit is most pronounced when reallocation would
otherwise force a full copy of the string.
If you don't know the exact capacity, passing a value larger than necessary still avoids reallocation, at the cost of using more memory than is needed.
For more details, see Str.reserve.
Increase a string's capacity by at least the given number of additional bytes.
When you plan to append more bytes onto a string, Str.reserve can help avoid intermediate reallocations during a chain of Str.concat calls. Consider the following example, which does not use Str.reserve:
greeting = "Hello and welcome to Roc"
subject = "Awesome Programmer"
# Evaluates to "Hello and welcome to Roc, Awesome Programmer!"
hello_world =
greeting
.concat(", ")
.concat(subject)
.concat("!")
In this example:
1. We start with greeting, which has both a length and capacity of 24 bytes.
2. .concat(", ") sees there isn't enough capacity for 2 more bytes, so
it allocates a new 26-byte buffer, copies the existing 24 bytes into
it, and writes ", " at the end. The old allocation is deallocated.
3. .concat(subject) repeats the process: allocate a 44-byte buffer,
copy the 26 existing bytes, write "Awesome Programmer".
4. .concat("!") repeats once more: allocate 45 bytes, copy 44, write "!".
With Str.reserve, the chain only needs one allocation up front:
hello_world =
greeting
.reserve(21)
.concat(", ")
.concat(subject)
.concat("!")
Here, .reserve(21) ensures there is room for an additional 21 bytes
(", " + "Awesome Programmer" + "!"), allocating a 45-byte buffer
and copying greeting into it. The subsequent Str.concat calls all fit
in that capacity and do not need to reallocate.
Whether this is actually faster depends on the system allocator: many allocators can extend an existing allocation in place, in which case the per-concat reallocation is cheap and Str.reserve makes little observable difference. The benefit is most pronounced when reallocation would otherwise force a full copy of the string.
Str.reserve is not free — when more capacity is needed, it always performs a heap allocation. Only use it when you actually expect to make use of the extra capacity.
When you don't know exactly how many bytes you'll need, choosing a value somewhat higher than necessary is usually safe; a value that's too low may force later reallocation, while a value much higher than necessary just wastes memory.
If you plan to use Str.reserve on an empty string, use Str.with_capacity instead.
Shrink the memory footprint of a str such that its capacity and length are equal. Note: This will also convert seamless slices to regular lists.
Returns a List of the string's U8 UTF-8 code units. (To split the string into a List of smaller Str values instead of U8 values, see Str.split_on.)
expect "Roc".to_utf8() == [82, 111, 99]
expect "鹏".to_utf8() == [233, 185, 143]
expect "சி".to_utf8() == [224, 174, 154, 224, 174, 191]
expect "🐦".to_utf8() == [240, 159, 144, 166]
from_utf8_lossy : List(U8) -> Str
Converts a List of U8 UTF-8 code units to a string. Any grouping of invalid byte sequences are replaced with a single unicode replacement character '�'.
An invalid byte sequence is defined as - a 2-byte-sequence starting byte, followed by less than 1 continuation byte - a 3-byte-sequence starting byte, followed by less than 2 continuation bytes - a 4-byte-sequence starting byte, followed by less than 3 continuation bytes - an invalid codepoint from the surrogate pair block - an invalid codepoint greater than 0x110000 encoded as a 4-byte sequence - any valid codepoint encoded as an incorrect sequence, for instance a codepoint that should be a 2-byte sequence encoded as a 3- or 4-byte sequence
expect Str.from_utf8_lossy([82, 111, 99, 240, 159, 144, 166]) == "Roc🐦"
expect Str.from_utf8_lossy([82, 255, 99]) == "R�c"
expect Str.from_utf8_lossy([82, 0xED, 0xA0, 0xBD, 99]) == "R�c"
Converts a List of U8 UTF-8 code units to a string.
Returns Err if the given bytes are invalid UTF-8, and returns Ok("") when given [].
expect Str.from_utf8([82, 111, 99]) == Ok("Roc")
expect Str.from_utf8([233, 185, 143]) == Ok("鹏")
expect Str.from_utf8([224, 174, 154, 224, 174, 191]) == Ok("சி")
expect Str.from_utf8([240, 159, 144, 166]) == Ok("🐦")
expect Str.from_utf8([]) == Ok("")
expect Str.from_utf8([255]).is_err()
Split a string around a separator.
Passing "" for the separator is not useful;
it returns the original string wrapped in a List.
expect "1,2,3".split_on(",") == ["1","2","3"]
expect "1,2,3".split_on("") == ["1,2,3"]
Combines a List of strings into a single string, with a separator string in between each.
expect Str.join_with(["one", "two", "three"], ", ") == "one, two, three"
expect Str.join_with(["1", "2", "3", "4"], ".") == "1.2.3.4"
Returns True if the two strings are exactly the same.
Returns a human-readable representation of a value, useful for debugging.
Encode a string using a format that provides encode_str
decode : src, fmt -> (Try(Str, err), src) where { fmt.decode_str : fmt, src -> (Try(Str, err), src) }
Decode a string using a format that provides decode_str
Utf8Problem
:= [InvalidStartByte, UnexpectedEndOfSequence, ExpectedContinuation, OverlongEncoding, CodepointTooLarge, EncodesSurrogateHalf]
is_eq : Utf8Problem, Utf8Problem -> Bool