fn unicode_decode_checks() -> Bool { let ascii: Maybe = std.unicode.decodeAt("A", 0) if !ascii.has || ascii.value != 65 { return false } let accent: Maybe = std.unicode.decodeAt("xé", 1) if !accent.has || accent.value != 233 { return false } let emoji: Maybe = std.unicode.decodeAt("💯", 0) if !emoji.has || emoji.value != 128175 { return false } let continuation: Maybe = std.unicode.decodeAt("é", 1) if continuation.has { return false } var overlong: [2]u8 = [192_u8, 175_u8] let bad: Maybe = std.unicode.decodeAt(overlong, 0) if bad.has { return false } var surrogate: [3]u8 = [237_u8, 160_u8, 128_u8] let lone: Maybe = std.unicode.decodeAt(surrogate, 0) let next: Maybe = std.unicode.nextIndex("aé", 1) return !lone.has && next.has && next.value == 3 } fn unicode_iteration_checks() -> Bool { let text: Span = std.mem.span("aé💯") var index: usize = 0 var count: usize = 0 while index < std.mem.len(text) { let width: Maybe = std.unicode.widthAt(text, index) if !width.has { return false } index = index + width.value count = count + 1 } let total: Maybe = std.text.utf8Len(text) return count == 3 && (total.has && total.value == 3) } fn unicode_encode_checks() -> Bool { var two_storage: [4]u8 = [0; 4] let two_buffer: MutSpan = two_storage let two: Maybe> = std.unicode.encode(two_buffer, 233) if !two.has || (std.mem.len(two.value) != 2 || (two.value[0] != 195_u8 || two.value[1] != 169_u8)) { return false } var four_storage: [4]u8 = [0; 4] let four_buffer: MutSpan = four_storage let four: Maybe> = std.unicode.encode(four_buffer, 128175) if !four.has || std.mem.len(four.value) != 4 { return false } let echo: Maybe = std.unicode.decodeAt(four.value, 0) if !echo.has || echo.value != 128175 { return false } var reject_storage: [4]u8 = [0; 4] let reject_buffer: MutSpan = reject_storage let surrogate: Maybe> = std.unicode.encode(reject_buffer, 55296) if surrogate.has { return false } var big_storage: [4]u8 = [0; 4] let big_buffer: MutSpan = big_storage let too_big: Maybe> = std.unicode.encode(big_buffer, 1114112) if too_big.has { return false } let max_width: Maybe = std.unicode.encodedWidth(1114111) let bad_width: Maybe = std.unicode.encodedWidth(56000) let one_width: Maybe = std.unicode.encodedWidth(65) if !max_width.has || max_width.value != 4 { return false } if bad_width.has { return false } return one_width.has && one_width.value == 1 } fn unicode_class_checks() -> Bool { return std.unicode.isDigit(53) && !std.unicode.isDigit(97) && std.unicode.isWord(95) && (std.unicode.isWord(122) && !std.unicode.isWord(233)) && std.unicode.isSpace(32) && (std.unicode.isSpace(8195) && (std.unicode.isSpace(12288) && !std.unicode.isSpace(65))) } fn unicode_status_checks() -> Bool { var truncated: [2]u8 = [226_u8, 130_u8] var continuation: [1]u8 = [128_u8] var overlong: [2]u8 = [192_u8, 175_u8] if std.unicode.decodeStatusAt("é", 0) != 0_u32 { return false } if std.unicode.decodeStatusAt(truncated, 0) != 4_u32 { return false } if std.unicode.decodeStatusAt(continuation, 0) != 2_u32 { return false } if std.unicode.decodeStatusAt(overlong, 0) != 6_u32 { return false } if std.unicode.invalidIndex("aé") != std.mem.len("aé") { return false } if std.unicode.invalidIndex(truncated) != 0 { return false } return std.mem.eql(std.unicode.statusName(4_u32), "truncated sequence") } pub fn main(world: World) -> Void raises { if unicode_decode_checks() && unicode_iteration_checks() && (unicode_encode_checks() && (unicode_class_checks() && unicode_status_checks())) { check world.out.write("std unicode ok\n") } else { check world.out.write("std unicode failed\n") } }