## 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: char) = 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): char? = 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): char? = ... ## 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: char) = ... ## 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: char) = ... ## 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): char? = ... ## 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[char]. Reallocates. pub func to(self: str): list[char] = var res: list[char] 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)