fn __zero_std_str_is_ascii_space(byte: u8) -> Bool { return byte == 32_u8 || byte == 9_u8 || (byte == 10_u8 || byte == 13_u8) } fn __zero_std_str_to_lower_byte(byte: u8) -> u8 { if byte >= 65_u8 && byte <= 90_u8 { return byte + 32_u8 } return byte } fn __zero_std_str_to_upper_byte(byte: u8) -> u8 { if byte >= 97_u8 && byte <= 122_u8 { return byte - 32_u8 } return byte } fn __zero_std_str_copy(buffer: MutSpan, text: Span) -> Maybe> { let len: usize = std.mem.len(text) if len > std.mem.len(buffer) { return null } var index: usize = 0 while index < len { buffer[index] = text[index] index = index + 1 } return buffer[..len] } fn __zero_std_str_concat(buffer: MutSpan, left: Span, right: Span) -> Maybe> { let left_len: usize = std.mem.len(left) let right_len: usize = std.mem.len(right) if left_len > std.mem.len(buffer) || right_len > std.mem.len(buffer) - left_len { return null } var index: usize = 0 while index < left_len { buffer[index] = left[index] index = index + 1 } var right_index: usize = 0 while right_index < right_len { buffer[left_len + right_index] = right[right_index] right_index = right_index + 1 } return buffer[..left_len + right_len] } fn __zero_std_str_repeat(buffer: MutSpan, text: Span, count: usize) -> Maybe> { let len: usize = std.mem.len(text) if count > 0 && len > std.mem.len(buffer) / count { return null } var out: usize = 0 var repetition: usize = 0 while repetition < count { var index: usize = 0 while index < len { buffer[out] = text[index] out = out + 1 index = index + 1 } repetition = repetition + 1 } return buffer[..out] } fn __zero_std_str_replace(buffer: MutSpan, text: Span, old: Span, replacement: Span) -> Maybe> { let old_len: usize = std.mem.len(old) if old_len == 0 { return null } let text_len: usize = std.mem.len(text) var read: usize = 0 var write: usize = 0 while read < text_len { if old_len <= text_len - read && __zero_std_str_starts_with(text[read..], old) { if std.mem.len(replacement) > std.mem.len(buffer) - write { return null } var new_index: usize = 0 while new_index < std.mem.len(replacement) { buffer[write] = replacement[new_index] write = write + 1 new_index = new_index + 1 } read = read + old_len } else { if write >= std.mem.len(buffer) { return null } buffer[write] = text[read] write = write + 1 read = read + 1 } } return buffer[..write] } fn __zero_std_str_to_lower_ascii(buffer: MutSpan, text: Span) -> Maybe> { let len: usize = std.mem.len(text) if len > std.mem.len(buffer) { return null } var index: usize = 0 while index < len { buffer[index] = __zero_std_str_to_lower_byte(text[index]) index = index + 1 } return buffer[..len] } fn __zero_std_str_to_upper_ascii(buffer: MutSpan, text: Span) -> Maybe> { let len: usize = std.mem.len(text) if len > std.mem.len(buffer) { return null } var index: usize = 0 while index < len { buffer[index] = __zero_std_str_to_upper_byte(text[index]) index = index + 1 } return buffer[..len] } fn __zero_std_str_reverse(buffer: MutSpan, text: Span) -> Maybe> { let len: usize = std.mem.len(text) if len > std.mem.len(buffer) { return null } var index: usize = 0 while index < len { buffer[index] = text[len - 1 - index] index = index + 1 } return buffer[..len] } fn __zero_std_str_count_byte(text: Span, byte: u8) -> usize { var index: usize = 0 var count: usize = 0 while index < std.mem.len(text) { if text[index] == byte { count = count + 1 } index = index + 1 } return count } fn __zero_std_str_starts_with(text: Span, prefix: Span) -> Bool { let prefix_len: usize = std.mem.len(prefix) if prefix_len > std.mem.len(text) { return false } var index: usize = 0 while index < prefix_len { if text[index] != prefix[index] { return false } index = index + 1 } return true } fn __zero_std_str_ends_with(text: Span, suffix: Span) -> Bool { let text_len: usize = std.mem.len(text) let suffix_len: usize = std.mem.len(suffix) if suffix_len > text_len { return false } let start: usize = text_len - suffix_len var index: usize = 0 while index < suffix_len { if text[start + index] != suffix[index] { return false } index = index + 1 } return true } fn __zero_std_str_contains(text: Span, needle: Span) -> Bool { let needle_len: usize = std.mem.len(needle) if needle_len == 0 { return true } let text_len: usize = std.mem.len(text) if needle_len > text_len { return false } let last_start: usize = text_len - needle_len var start: usize = 0 while start <= last_start { var offset: usize = 0 var same: Bool = true while same && offset < needle_len { if text[start + offset] != needle[offset] { same = false } else { offset = offset + 1 } } if same { return true } start = start + 1 } return false } fn __zero_std_str_index_of(text: Span, needle: Span) -> usize { let needle_len: usize = std.mem.len(needle) if needle_len == 0 { return 0 } let text_len: usize = std.mem.len(text) if needle_len > text_len { return text_len } let last_start: usize = text_len - needle_len var start: usize = 0 while start <= last_start { var offset: usize = 0 var same: Bool = true while same && offset < needle_len { if text[start + offset] != needle[offset] { same = false } else { offset = offset + 1 } } if same { return start } start = start + 1 } return text_len } fn __zero_std_str_last_index_of(text: Span, needle: Span) -> usize { let needle_len: usize = std.mem.len(needle) let text_len: usize = std.mem.len(text) if needle_len == 0 { return text_len } if needle_len > text_len { return text_len } var start: usize = text_len - needle_len + 1 while start > 0 { start = start - 1 var offset: usize = 0 var same: Bool = true while same && offset < needle_len { if text[start + offset] != needle[offset] { same = false } else { offset = offset + 1 } } if same { return start } } return text_len } fn __zero_std_str_count(text: Span, needle: Span) -> usize { let needle_len: usize = std.mem.len(needle) if needle_len == 0 { return std.mem.len(text) + 1 } var index: usize = 0 var count: usize = 0 while index <= std.mem.len(text) { let rest: Span = text[index..] let found: usize = __zero_std_str_index_of(rest, needle) if found == std.mem.len(rest) { return count } count = count + 1 index = index + found + needle_len } return count } fn __zero_std_str_split_count(text: Span, sep: Span) -> usize { if std.mem.len(sep) == 0 { return 0 } return __zero_std_str_count(text, sep) + 1 } fn __zero_std_str_split(text: Span, sep: Span, part_index: usize) -> Maybe> { let sep_len: usize = std.mem.len(sep) if sep_len == 0 { return null } var current: usize = 0 var start: usize = 0 while start <= std.mem.len(text) { let rest: Span = text[start..] let found: usize = __zero_std_str_index_of(rest, sep) let end: usize = start + found if current == part_index { return text[start..end] } if found == std.mem.len(rest) { return null } current = current + 1 start = end + sep_len } return null } fn __zero_std_str_eql_ignore_ascii_case(left: Span, right: Span) -> Bool { if std.mem.len(left) != std.mem.len(right) { return false } var index: usize = 0 while index < std.mem.len(left) { if __zero_std_str_to_lower_byte(left[index]) != __zero_std_str_to_lower_byte(right[index]) { return false } index = index + 1 } return true } fn __zero_std_str_trim_ascii(text: Span) -> Span { var start: usize = 0 var end: usize = std.mem.len(text) while start < end && __zero_std_str_is_ascii_space(text[start]) { start = start + 1 } while end > start && __zero_std_str_is_ascii_space(text[end - 1]) { end = end - 1 } return text[start..end] } fn __zero_std_str_trim_start_ascii(text: Span) -> Span { var start: usize = 0 while start < std.mem.len(text) && __zero_std_str_is_ascii_space(text[start]) { start = start + 1 } return text[start..] } fn __zero_std_str_trim_end_ascii(text: Span) -> Span { var end: usize = std.mem.len(text) while end > 0 && __zero_std_str_is_ascii_space(text[end - 1]) { end = end - 1 } return text[..end] } fn __zero_std_str_field_count_ascii(text: Span) -> usize { return __zero_std_str_word_count_ascii(text) } fn __zero_std_str_field_ascii(text: Span, field_index: usize) -> Maybe> { var index: usize = 0 var current: usize = 0 while index < std.mem.len(text) { while index < std.mem.len(text) && __zero_std_str_is_ascii_space(text[index]) { index = index + 1 } if index >= std.mem.len(text) { return null } let start: usize = index while index < std.mem.len(text) && !__zero_std_str_is_ascii_space(text[index]) { index = index + 1 } if current == field_index { return text[start..index] } current = current + 1 } return null } fn __zero_std_str_line_count(text: Span) -> usize { if std.mem.len(text) == 0 { return 0 } var count: usize = 1 var index: usize = 0 while index < std.mem.len(text) { if text[index] == 10_u8 && index + 1 < std.mem.len(text) { count = count + 1 } index = index + 1 } return count } fn __zero_std_str_line(text: Span, line_index: usize) -> Maybe> { if std.mem.len(text) == 0 { return null } var current: usize = 0 var start: usize = 0 var index: usize = 0 while index <= std.mem.len(text) { if index == std.mem.len(text) || text[index] == 10_u8 { if index == std.mem.len(text) && start == std.mem.len(text) { return null } var end: usize = index if end > start && text[end - 1] == 13_u8 { end = end - 1 } if current == line_index { return text[start..end] } current = current + 1 start = index + 1 } index = index + 1 } return null } fn __zero_std_str_word_count_ascii(text: Span) -> usize { var index: usize = 0 var count: usize = 0 var in_word: Bool = false while index < std.mem.len(text) { if __zero_std_str_is_ascii_space(text[index]) { in_word = false } else if !in_word { count = count + 1 in_word = true } index = index + 1 } return count }