diff --git a/gojo/fmt/fmt.mojo b/gojo/fmt/fmt.mojo index 3b31275..8997e50 100644 --- a/gojo/fmt/fmt.mojo +++ b/gojo/fmt/fmt.mojo @@ -124,19 +124,19 @@ fn format_bytes(format: String, arg: List[Byte]) -> String: fn format_integer(format: String, arg: Int) -> String: var verb = find_first_verb(format, List[String]("%x", "%X", "%d", "%q")) - var arg_to_place = String(arg) + var arg_to_place = str(arg) if verb == "%x": - arg_to_place = String(convert_base10_to_base16(arg)).lower() + arg_to_place = str(convert_base10_to_base16(arg)).lower() elif verb == "%X": - arg_to_place = String(convert_base10_to_base16(arg)).upper() + arg_to_place = str(convert_base10_to_base16(arg)).upper() elif verb == "%q": - arg_to_place = "'" + String(arg) + "'" + arg_to_place = "'" + str(arg) + "'" return replace_first(format, verb, arg_to_place) fn format_float(format: String, arg: Float64) -> String: - return replace_first(format, String("%f"), arg) + return replace_first(format, str("%f"), str(arg)) fn format_boolean(format: String, arg: Bool) -> String: @@ -214,6 +214,6 @@ fn printf(formatting: String, *args: Args) raises: elif argument.isa[Bool](): text = format_boolean(text, argument[Bool]) else: - raise Error("Unknown for argument #" + String(i)) + raise Error("Unknown for argument #" + str(i)) print(text) diff --git a/gojo/io/io.mojo b/gojo/io/io.mojo index c9fc8d1..1c6901b 100644 --- a/gojo/io/io.mojo +++ b/gojo/io/io.mojo @@ -17,7 +17,7 @@ fn write_string[W: Writer](inout writer: W, string: String) -> (Int, Error): Returns: The number of bytes written and an error, if any. """ - return writer.write(string.as_bytes()) + return writer.write(string.as_bytes_slice()) fn write_string[W: StringWriter](inout writer: W, string: String) -> (Int, Error): @@ -34,7 +34,7 @@ fn write_string[W: StringWriter](inout writer: W, string: String) -> (Int, Error return writer.write_string(string) -fn read_at_least[R: Reader](inout reader: R, inout dest: List[Byte], min: Int) -> (Int, Error): +fn read_at_least[R: Reader](inout reader: R, inout dest: Span[Byte], min: Int) -> (Int, Error): """Reads from r into buf until it has read at least min bytes. It returns the number of bytes copied and an error if fewer bytes were read. The error is EOF only if no bytes were read. @@ -70,7 +70,7 @@ fn read_at_least[R: Reader](inout reader: R, inout dest: List[Byte], min: Int) - return total_bytes_read, error -fn read_full[R: Reader](inout reader: R, inout dest: List[Byte]) -> (Int, Error): +fn read_full[R: Reader](inout reader: R, inout dest: Span[Byte]) -> (Int, Error): """Reads exactly len(buf) bytes from r into buf. It returns the number of bytes copied and an error if fewer bytes were read. The error is EOF only if no bytes were read. @@ -132,7 +132,7 @@ fn read_full[R: Reader](inout reader: R, inout dest: List[Byte]) -> (Int, Error) # } -# fn copy_buffer[W: Writer, R: Reader](dst: W, src: R, buf: List[Byte]) raises -> Int64: +# fn copy_buffer[W: Writer, R: Reader](dst: W, src: R, buf: Span[Byte]) raises -> Int64: # """Actual implementation of copy and CopyBuffer. # if buf is nil, one is allocated. # """ @@ -152,11 +152,11 @@ fn read_full[R: Reader](inout reader: R, inout dest: List[Byte]) -> (Int, Error) # return written -# fn copy_buffer[W: Writer, R: ReaderWriteTo](dst: W, src: R, buf: List[Byte]) -> Int64: +# fn copy_buffer[W: Writer, R: ReaderWriteTo](dst: W, src: R, buf: Span[Byte]) -> Int64: # return src.write_to(dst) -# fn copy_buffer[W: WriterReadFrom, R: Reader](dst: W, src: R, buf: List[Byte]) -> Int64: +# fn copy_buffer[W: WriterReadFrom, R: Reader](dst: W, src: R, buf: Span[Byte]) -> Int64: # return dst.read_from(src) # # LimitReader returns a Reader that reads from r @@ -421,7 +421,7 @@ fn read_all[R: Reader](inout reader: R) -> (List[Byte], Error): var at_eof: Bool = False while True: - var temp = List[Byte](capacity=BUFFER_SIZE) + var temp = Span(List[Byte](capacity=BUFFER_SIZE)) var bytes_read: Int var err: Error bytes_read, err = reader.read(temp) diff --git a/gojo/io/traits.mojo b/gojo/io/traits.mojo index 97c3aa5..7b69b06 100644 --- a/gojo/io/traits.mojo +++ b/gojo/io/traits.mojo @@ -78,7 +78,7 @@ trait Reader(Movable): Implementations must not retain p.""" - fn read(inout self, inout dest: List[Byte]) -> (Int, Error): + fn read(inout self, inout dest: Span[Byte]) -> (Int, Error): ... @@ -94,7 +94,7 @@ trait Writer(Movable): Implementations must not retain p. """ - fn write(inout self, src: List[Byte]) -> (Int, Error): + fn write(inout self, src: Span[Byte]) -> (Int, Error): ... @@ -227,7 +227,7 @@ trait ReaderAt: Implementations must not retain p.""" - fn read_at(self, inout dest: List[Byte], off: Int64) -> (Int, Error): + fn read_at(self, inout dest: Span[Byte], off: Int64) -> (Int, Error): ... @@ -248,7 +248,7 @@ trait WriterAt: Implementations must not retain p.""" - fn write_at(self, src: List[Byte], off: Int64) -> (Int, Error): + fn write_at(self, src: Span[Byte], off: Int64) -> (Int, Error): ... diff --git a/gojo/net/address.mojo b/gojo/net/address.mojo index 01bf25f..9bf5a50 100644 --- a/gojo/net/address.mojo +++ b/gojo/net/address.mojo @@ -47,8 +47,8 @@ struct TCPAddr(Addr): fn __str__(self) -> String: if self.zone != "": - return join_host_port(String(self.ip) + "%" + self.zone, self.port) - return join_host_port(self.ip, self.port) + return join_host_port(str(self.ip) + "%" + self.zone, str(self.port)) + return join_host_port(self.ip, str(self.port)) fn network(self) -> String: return NetworkType.tcp.value @@ -69,7 +69,7 @@ fn resolve_internet_addr(network: String, address: String) raises -> TCPAddr: if address != "": var host_port = split_host_port(address) host = host_port.host - port = host_port.port + port = str(host_port.port) portnum = atol(port.__str__()) elif network == NetworkType.ip.value or network == NetworkType.ip4.value or network == NetworkType.ip6.value: if address != "": diff --git a/gojo/net/dial.mojo b/gojo/net/dial.mojo index 5effd65..f5719e6 100644 --- a/gojo/net/dial.mojo +++ b/gojo/net/dial.mojo @@ -11,7 +11,6 @@ struct Dialer: var tcp_addr = resolve_internet_addr(network, address) var socket = Socket(local_address=self.local_address) socket.connect(tcp_addr.ip, tcp_addr.port) - print(String("Connected to ") + socket.remote_address) return TCPConnection(socket^) diff --git a/gojo/net/ip.mojo b/gojo/net/ip.mojo index 76a56bd..e76d5cc 100644 --- a/gojo/net/ip.mojo +++ b/gojo/net/ip.mojo @@ -1,4 +1,5 @@ from utils.variant import Variant +from utils.static_tuple import StaticTuple from sys.info import os_is_linux, os_is_macos from ..syscall.types import ( c_int, @@ -102,15 +103,15 @@ fn get_ip_address(host: String) raises -> String: var address_family: Int32 = 0 var address_length: UInt32 = 0 if result.isa[addrinfo](): - var addrinfo = result.get[addrinfo]() - ai_addr = addrinfo[].ai_addr - address_family = addrinfo[].ai_family - address_length = addrinfo[].ai_addrlen + var addrinfo = result[addrinfo] + ai_addr = addrinfo.ai_addr + address_family = addrinfo.ai_family + address_length = addrinfo.ai_addrlen else: - var addrinfo = result.get[addrinfo_unix]() - ai_addr = addrinfo[].ai_addr - address_family = addrinfo[].ai_family - address_length = addrinfo[].ai_addrlen + var addrinfo = result[addrinfo_unix] + ai_addr = addrinfo.ai_addr + address_family = addrinfo.ai_family + address_length = addrinfo.ai_addrlen if not ai_addr: print("ai_addr is null") diff --git a/gojo/net/socket.mojo b/gojo/net/socket.mojo index 10fcd7b..e019255 100644 --- a/gojo/net/socket.mojo +++ b/gojo/net/socket.mojo @@ -355,7 +355,7 @@ struct Socket(FileDescriptorBase): # Try to send all the data in the buffer. If it did not send all the data, keep trying but start from the offset of the last successful send. while total_bytes_sent < len(src): if attempts > max_attempts: - raise Error("Failed to send message after " + String(max_attempts) + " attempts.") + raise Error("Failed to send message after " + str(max_attempts) + " attempts.") var bytes_sent = send( self.sockfd.fd, diff --git a/gojo/net/tcp.mojo b/gojo/net/tcp.mojo index 6a59db8..41c6912 100644 --- a/gojo/net/tcp.mojo +++ b/gojo/net/tcp.mojo @@ -26,7 +26,7 @@ fn resolve_internet_addr(network: String, address: String) raises -> TCPAddr: if address != "": var host_port = split_host_port(address) host = host_port.host - port = host_port.port + port = str(host_port.port) portnum = atol(port.__str__()) elif network == NetworkType.ip.value or network == NetworkType.ip4.value or network == NetworkType.ip6.value: if address != "": @@ -50,7 +50,7 @@ struct ListenConfig(CollectionElement): socket.bind(tcp_addr.ip, tcp_addr.port) socket.set_socket_option(SO_REUSEADDR, 1) socket.listen() - print(String("Listening on ") + socket.local_address) + print(str("Listening on ") + str(socket.local_address)) return TCPListener(socket^, self, network, address) diff --git a/gojo/strings/builder.mojo b/gojo/strings/builder.mojo index 49e7297..8ab2434 100644 --- a/gojo/strings/builder.mojo +++ b/gojo/strings/builder.mojo @@ -3,139 +3,11 @@ from ..builtins import Byte @value -struct LegacyStringBuilder(Stringable, Sized, io.Writer, io.ByteWriter, io.StringWriter): +struct StringBuilder[growth_factor: Float32 = 2](Stringable, Sized, io.Writer, io.StringWriter): """ A string builder class that allows for efficient string management and concatenation. This class is useful when you need to build a string by appending multiple strings - together. It is around 20x faster than using the `+` operator to concatenate - strings because it avoids the overhead of creating and destroying many - intermediate strings and performs memcopy operations. - - The result is a more efficient when building larger string concatenations. It - is generally not recommended to use this class for small concatenations such as - a few strings like `a + b + c + d` because the overhead of creating the string - builder and appending the strings is not worth the performance gain. - - Example: - ``` - from strings.builder import StringBuilder - - var sb = StringBuilder() - sb.write_string("mojo") - sb.write_string("jojo") - print(sb) # mojojojo - ``` - """ - - var _vector: List[Byte] - - fn __init__(inout self, *, size: Int = 4096): - self._vector = List[Byte](capacity=size) - - fn __str__(self) -> String: - """ - Converts the string builder to a string. - - Returns: - The string representation of the string builder. Returns an empty - string if the string builder is empty. - """ - var copy = List[Byte](self._vector) - if copy[-1] != 0: - copy.append(0) - return String(copy) - - fn get_bytes(self) -> List[Byte]: - """ - Returns a deepcopy of the byte array of the string builder. - - Returns: - The byte array of the string builder. - """ - return List[Byte](self._vector) - - fn get_null_terminated_bytes(self) -> List[Byte]: - """ - Returns a deepcopy of the byte array of the string builder with a null terminator. - - Returns: - The byte array of the string builder with a null terminator. - """ - var copy = List[Byte](self._vector) - if copy[-1] != 0: - copy.append(0) - - return copy - - fn write(inout self, src: List[Byte]) -> (Int, Error): - """ - Appends a byte array to the builder buffer. - - Args: - src: The byte array to append. - """ - self._vector.extend(src) - return len(src), Error() - - fn write_byte(inout self, byte: Byte) -> (Int, Error): - """ - Appends a byte array to the builder buffer. - - Args: - byte: The byte array to append. - """ - self._vector.append(byte) - return 1, Error() - - fn write_string(inout self, src: String) -> (Int, Error): - """ - Appends a string to the builder buffer. - - Args: - src: The string to append. - """ - var string_buffer = src.as_bytes() - self._vector.extend(string_buffer) - return len(string_buffer), Error() - - fn __len__(self) -> Int: - """ - Returns the length of the string builder. - - Returns: - The length of the string builder. - """ - return len(self._vector) - - fn __getitem__(self, index: Int) -> String: - """ - Returns the string at the given index. - - Args: - index: The index of the string to return. - - Returns: - The string at the given index. - """ - return self._vector[index] - - fn __setitem__(inout self, index: Int, value: Byte): - """ - Sets the string at the given index. - - Args: - index: The index of the string to set. - value: The value to set. - """ - self._vector[index] = value - - -@value -struct StringBuilder[growth_factor: Float32 = 2](Stringable, Sized): - """ - A string builder class that allows for efficient string management and concatenation. - This class is useful when you need to build a string by appending multiple strings - together. The performance increase is not linear. Compared to string concatenation, + together. The performance increase is not linear. Compared to string concatenation, I've observed around 20-30x faster for writing and rending ~4KB and up to 2100x-2300x for ~4MB. This is because it avoids the overhead of creating and destroying many intermediate strings and performs memcopy operations. @@ -167,6 +39,21 @@ struct StringBuilder[growth_factor: Float32 = 2](Stringable, Sized): self.size = 0 self.capacity = capacity + @always_inline + fn __del__(owned self): + if self.data: + self.data.free() + + @always_inline + fn __len__(self) -> Int: + """ + Returns the length of the string builder. + + Returns: + The length of the string builder. + """ + return self.size + @always_inline fn __str__(self) -> String: """ @@ -184,17 +71,13 @@ struct StringBuilder[growth_factor: Float32 = 2](Stringable, Sized): fn render(self: Reference[Self]) -> StringSlice[self.is_mutable, self.lifetime]: """ Return a StringSlice view of the data owned by the builder. + Slightly faster than __str__, 10-20% faster in limited testing. Returns: The string representation of the string builder. Returns an empty string if the string builder is empty. """ return StringSlice[self.is_mutable, self.lifetime](unsafe_from_utf8_strref=StringRef(self[].data, self[].size)) - @always_inline - fn __del__(owned self): - if self.data: - self.data.free() - @always_inline fn _resize(inout self, capacity: Int) -> None: """ @@ -220,7 +103,10 @@ struct StringBuilder[growth_factor: Float32 = 2](Stringable, Sized): src: The byte array to append. """ if len(src) > self.capacity - self.size: - self._resize(int(self.capacity * growth_factor)) + var new_capacity = int(self.capacity * growth_factor) + if new_capacity < self.capacity + len(src): + new_capacity = self.capacity + len(src) + self._resize(new_capacity) memcpy(self.data.offset(self.size), src._data, len(src)) self.size += len(src) @@ -236,13 +122,3 @@ struct StringBuilder[growth_factor: Float32 = 2](Stringable, Sized): src: The string to append. """ return self.write(src.as_bytes_slice()) - - @always_inline - fn __len__(self) -> Int: - """ - Returns the length of the string builder. - - Returns: - The length of the string builder. - """ - return self.size diff --git a/gojo/strings/reader.mojo b/gojo/strings/reader.mojo index 8d8af28..18aa9b4 100644 --- a/gojo/strings/reader.mojo +++ b/gojo/strings/reader.mojo @@ -39,12 +39,12 @@ struct Reader(Sized, io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.S """ return Int64(len(self.string)) - fn read(inout self, inout dest: List[Byte]) -> (Int, Error): - """Reads from the underlying string into the provided List[Byte] object. + fn read(inout self, inout dest: Span[Byte]) -> (Int, Error): + """Reads from the underlying string into the provided Span[Byte] object. Implements the [io.Reader] trait. Args: - dest: The destination List[Byte] object to read into. + dest: The destination Span[Byte] object to read into. Returns: The number of bytes read into dest. @@ -53,17 +53,21 @@ struct Reader(Sized, io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.S return 0, Error(io.EOF) self.prev_rune = -1 - var bytes_written = copy(dest, self.string[int(self.read_pos) :].as_bytes()) - self.read_pos += Int64(bytes_written) + var str_to_read = self.string[int(self.read_pos) :] + var bytes_written: Int + memcpy(dest.unsafe_ptr().offset(len(dest)), str_to_read.unsafe_uint8_ptr(), len(str_to_read)) + bytes_written = len(str_to_read) + + self.read_pos += Int64(len(str_to_read)) return bytes_written, Error() - fn read_at(self, inout dest: List[Byte], off: Int64) -> (Int, Error): - """Reads from the Reader into the dest List[Byte] starting at the offset off. + fn read_at(self, inout dest: Span[Byte], off: Int64) -> (Int, Error): + """Reads from the Reader into the dest Span[Byte] starting at the offset off. It returns the number of bytes read into dest and an error if any. Implements the [io.ReaderAt] trait. Args: - dest: The destination List[Byte] object to read into. + dest: The destination Span[Byte] object to read into. off: The byte offset to start reading from. Returns: @@ -77,11 +81,12 @@ struct Reader(Sized, io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.S return 0, Error(io.EOF) var error = Error() - var copied_elements_count = copy(dest, self.string[int(off) :].as_bytes()) - if copied_elements_count < len(dest): - error = Error(io.EOF) + var str_to_read = self.string[int(off) :] + var bytes_written: Int + memcpy(dest.unsafe_ptr().offset(len(dest)), str_to_read.unsafe_uint8_ptr(), len(str_to_read)) + bytes_written = len(str_to_read) - return copied_elements_count, Error() + return bytes_written, Error() fn read_byte(inout self) -> (Byte, Error): """Reads the next byte from the underlying string. diff --git a/gojo/syscall/file.mojo b/gojo/syscall/file.mojo index d4095a5..f088260 100644 --- a/gojo/syscall/file.mojo +++ b/gojo/syscall/file.mojo @@ -22,7 +22,7 @@ fn close(fildes: c_int) -> c_int: return external_call["close", c_int, c_int](fildes) -fn open[*T: AnyType](path: Pointer[c_char], oflag: c_int, *args: *T) -> c_int: +fn open[*T: AnyType](path: UnsafePointer[c_char], oflag: c_int) -> c_int: """Libc POSIX `open` function Reference: https://man7.org/linux/man-pages/man3/open.3p.html Fn signature: int open(const char *path, int oflag, ...). @@ -30,61 +30,13 @@ fn open[*T: AnyType](path: Pointer[c_char], oflag: c_int, *args: *T) -> c_int: Args: path: A pointer to a C string containing the path to open. oflag: The flags to open the file with. - args: The optional arguments. Returns: A File Descriptor or -1 in case of failure """ - return external_call["open", c_int, Pointer[c_char], c_int](path, oflag, args) # FnName, RetType # Args + return external_call["open", c_int, UnsafePointer[c_char], c_int](path, oflag) # FnName, RetType # Args -fn openat[*T: AnyType](fd: c_int, path: Pointer[c_char], oflag: c_int, *args: *T) -> c_int: - """Libc POSIX `open` function - Reference: https://man7.org/linux/man-pages/man3/open.3p.html - Fn signature: int openat(int fd, const char *path, int oflag, ...). - - Args: - fd: A File Descriptor. - path: A pointer to a C string containing the path to open. - oflag: The flags to open the file with. - args: The optional arguments. - Returns: - A File Descriptor or -1 in case of failure - """ - return external_call["openat", c_int, c_int, Pointer[c_char], c_int]( # FnName, RetType # Args - fd, path, oflag, args - ) - - -fn printf[*T: AnyType](format: Pointer[c_char], *args: *T) -> c_int: - """Libc POSIX `printf` function - Reference: https://man7.org/linux/man-pages/man3/fprintf.3p.html - Fn signature: int printf(const char *restrict format, ...). - - Args: format: A pointer to a C string containing the format. - args: The optional arguments. - Returns: The number of bytes written or -1 in case of failure. - """ - return external_call[ - "printf", - c_int, # FnName, RetType - Pointer[c_char], # Args - ](format, args) - - -fn sprintf[*T: AnyType](s: Pointer[c_char], format: Pointer[c_char], *args: *T) -> c_int: - """Libc POSIX `sprintf` function - Reference: https://man7.org/linux/man-pages/man3/fprintf.3p.html - Fn signature: int sprintf(char *restrict s, const char *restrict format, ...). - - Args: s: A pointer to a buffer to store the result. - format: A pointer to a C string containing the format. - args: The optional arguments. - Returns: The number of bytes written or -1 in case of failure. - """ - return external_call["sprintf", c_int, Pointer[c_char], Pointer[c_char]](s, format, args) # FnName, RetType # Args - - -fn read(fildes: c_int, buf: Pointer[c_void], nbyte: c_size_t) -> c_int: +fn read(fildes: c_int, buf: UnsafePointer[c_void], nbyte: c_size_t) -> c_int: """Libc POSIX `read` function Reference: https://man7.org/linux/man-pages/man3/read.3p.html Fn signature: sssize_t read(int fildes, void *buf, size_t nbyte). @@ -94,10 +46,10 @@ fn read(fildes: c_int, buf: Pointer[c_void], nbyte: c_size_t) -> c_int: nbyte: The number of bytes to read. Returns: The number of bytes read or -1 in case of failure. """ - return external_call["read", c_ssize_t, c_int, Pointer[c_void], c_size_t](fildes, buf, nbyte) + return external_call["read", c_ssize_t, c_int, UnsafePointer[c_void], c_size_t](fildes, buf, nbyte) -fn write(fildes: c_int, buf: Pointer[c_void], nbyte: c_size_t) -> c_int: +fn write(fildes: c_int, buf: UnsafePointer[c_void], nbyte: c_size_t) -> c_int: """Libc POSIX `write` function Reference: https://man7.org/linux/man-pages/man3/write.3p.html Fn signature: ssize_t write(int fildes, const void *buf, size_t nbyte). @@ -107,4 +59,4 @@ fn write(fildes: c_int, buf: Pointer[c_void], nbyte: c_size_t) -> c_int: nbyte: The number of bytes to write. Returns: The number of bytes written or -1 in case of failure. """ - return external_call["write", c_ssize_t, c_int, Pointer[c_void], c_size_t](fildes, buf, nbyte) + return external_call["write", c_ssize_t, c_int, UnsafePointer[c_void], c_size_t](fildes, buf, nbyte) diff --git a/gojo/syscall/types.mojo b/gojo/syscall/types.mojo index 56693e7..ac7340a 100644 --- a/gojo/syscall/types.mojo +++ b/gojo/syscall/types.mojo @@ -1,34 +1,4 @@ -@value -struct Str: - var vector: List[c_char] - - fn __init__(inout self, string: String): - self.vector = List[c_char](capacity=len(string) + 1) - for i in range(len(string)): - self.vector.append(ord(string[i])) - self.vector.append(0) - - fn __init__(inout self, size: Int): - self.vector = List[c_char]() - self.vector.resize(size + 1, 0) - - fn __len__(self) -> Int: - for i in range(len(self.vector)): - if self.vector[i] == 0: - return i - return -1 - - fn to_string(self, size: Int) -> String: - var result: String = "" - for i in range(size): - result += chr(int(self.vector[i])) - return result - - fn __enter__(owned self: Self) -> Self: - return self^ - - -fn strlen(s: Pointer[c_char]) -> c_size_t: +fn strlen(s: UnsafePointer[c_char]) -> c_size_t: """Libc POSIX `strlen` function Reference: https://man7.org/linux/man-pages/man3/strlen.3p.html Fn signature: size_t strlen(const char *s). @@ -36,7 +6,7 @@ fn strlen(s: Pointer[c_char]) -> c_size_t: Args: s: A pointer to a C string. Returns: The length of the string. """ - return external_call["strlen", c_size_t, Pointer[c_char]](s) + return external_call["strlen", c_size_t, UnsafePointer[c_char]](s) # Adapted from https://github.com/crisadamo/mojo-Libc . Huge thanks to Cristian! diff --git a/tests/test_performance.mojo b/tests/test_performance.mojo index 67d7216..3ca905d 100644 --- a/tests/test_performance.mojo +++ b/tests/test_performance.mojo @@ -1,5 +1,5 @@ from time import now -from gojo.strings.builder import LegacyStringBuilder, StringBuilder +from gojo.strings.builder import StringBuilder from gojo.bytes import buffer from goodies import STDWriter diff --git a/tests/test_strings_stringbuilder.mojo b/tests/test_strings_stringbuilder.mojo index b4ff00b..f8fe3e7 100644 --- a/tests/test_strings_stringbuilder.mojo +++ b/tests/test_strings_stringbuilder.mojo @@ -18,25 +18,30 @@ fn test_write_string() raises: ) -fn test_write() raises: - var test = MojoTest("Testing strings.StringBuilder.write") +fn test_big_write(): + var test = MojoTest("Testing strings.StringBuilder.write_string with big Write") - # Create a string from the builder by writing bytes to it. - var builder = StringBuilder() - _ = builder.write(String("Hello").as_bytes()) - test.assert_equal(str(builder), "Hello") + # Create a string from the builder by writing strings to it. + var builder = StringBuilder(capacity=8) + + _ = builder.write_string("Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet") + test.assert_equal( + str(builder), + "Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet", + ) -fn test_write_byte() raises: - var test = MojoTest("Testing strings.StringBuilder.write_byte") + +fn test_write() raises: + var test = MojoTest("Testing strings.StringBuilder.write") # Create a string from the builder by writing bytes to it. var builder = StringBuilder() - _ = builder.write_byte(32) - test.assert_equal(str(builder), " ") + _ = builder.write(String("Hello").as_bytes_slice()) + test.assert_equal(str(builder), "Hello") fn main() raises: test_write_string() test_write() - test_write_byte() + test_big_write()