1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
## std.strings: The standard implementation of strings.
## This module is imported by default.
# reference: https://doc.rust-lang.org/std/string/struct.String.html
## A primitive string type.
##
## We do not want methods defined on `list[byte]` to carry over,
## so we define `str` as a newtype.
@[opaque]
pub type str = struct
data: list[byte]
## Initialize and return an empty string.
pub func init: str = { data = [] }
## Gets the length of a string.
## This is an O(n) operation, due to UTF-8 encoding.
pub func len(self: lent str): uint =
var res: uint
for _ in self do
res += 1
res
## Pushes a character to the end of a mutable string.
pub func push(self: mut str, val: chr) =
self.data.push(val.byte) # todo: obsolete by from/to conversion??
## Pushes an owned string to the end of a mutable string.
pub func push(self: mut str, val: str) =
self.data.push(val.bytes) # todo: obsolete by from/to conversion??
## Removes and returns the last character of a string, if it exists.
##
## SAFETY: We return early upon an empty string.
## And decrement by one char for a non-empty string.
@[safe]
pub func pop(self: mut str): chr? =
let char = self.chars.rev.next?
self.data.set_len(self.len - char.len) # this is normally unsafe.
Some(char)
## Returns the character at the provided index, if it exists.
pub func get(self: str, i: uint): chr? =
...
## Sets the character at the provided index, if it exists.
## As strings are packed, this may call str.grow and reallocate.
## oh fuck we have to insert + remove anyway
pub func set(self: mut str, i: uint, val: chr) =
...
## Inserts a character at an arbitrary position within a string.
## Panics on failure. (todo: can we do better?)
pub func insert(self: mut str, i: uint, val: chr) =
...
## Removes and returns a character at an arbitrary position within a string.
## Panics on failure. (todo: can we do better?)
pub func remove(self: mut str, i: uint): chr =
...
## Syntactic sugar for string appending.
pub func &=(a: mut str, b: str) =
a.push(b)
## The concatenation operator. Consumes two strings.
pub func &(a: str, b: str): str =
a.push(b)
a
## Conversion from a string to a list of bytes. Zero-cost.
pub func to(self: str): list[byte] = self.data
## Conversion from a str to a list[chr]. Reallocates.
pub func to(self: str): list[chr] =
var res: list[chr]
for char in self do res.push(char)
res
## Conversion from a char to an array of bytes. Zero-cost.
@[safe] # possibly unsafe?? depends on repr of arrays
pub func to(self: chr): array[byte, 4] = self.cast[array[byte, 4]]
# pub func next(self: mut StrIter)
# pub func peek(self: mut StrIter)
# pub func peek_nth(self: mut StrIter, i: uint)
|