lib/encoding/utf8+test: add strerror per Hare

This commit is contained in:
2026-05-19 16:50:02 +09:00
parent 8683202a4c
commit 2b46abe7d1
5 changed files with 44 additions and 0 deletions

View File

@@ -29,6 +29,12 @@ export type more = void;
// ref/hare/encoding/utf8/types.ha:9 — invalid UTF-8 sequence.
export type invalid = !void;
// ref/hare/encoding/utf8/types.ha:12 — fixed message; `invalid` carries
// no payload, so the rendering is constant.
export fn strerror(err: invalid) str = {
return "Invalid UTF-8";
};
// `done` is not a built-in singleton in ww (Hare ships it as part of
// the type system). Plain `void` (not `!void`): end-of-input is a
// continuation signal, not an error. lib/io spells its EOF the same

View File

@@ -12,6 +12,16 @@ import os;
let signalled: i32 = 0;
fn fail() void = { os.exit(signalled + 10); };
fn streq(a: str, b: str) bool = {
if (a.len != b.len) { return false; };
let i: i32 = 0;
for (i < a.len) {
if (a[i] != b[i]) { return false; };
i += 1;
};
return true;
};
// ---- runesz: byte length per range ------------------------------------
// ref/hare/encoding/utf8/rune.ha:5. Boundaries: 0x7F → 1, 0x80 → 2,
// 0x7FF → 2, 0x800 → 3, 0xFFFF → 3, 0x10000 → 4, 0x10FFFF → 4.
@@ -575,6 +585,15 @@ fn fail() void = { os.exit(signalled + 10); };
if (utf8.remaining(&d1).len != 0) { fail(); };
};
// ---- strerror: constant rendering -------------------------------------
// ref/hare/encoding/utf8/types.ha:12. `invalid` is payload-free; the
// renderer collapses to a single fixture row.
@test fn strerror_cases() void = {
let e: utf8.invalid;
if (!streq(utf8.strerror(e), "Invalid UTF-8")) { fail(); };
};
// ---- round-trip: encode → decode → equal rune --------------------------
@test fn roundtrip() void = {
@@ -636,5 +655,6 @@ export fn main() i32 = {
signalled = 33; prev_max_in_range();
signalled = 34; prev_min_out_of_range();
signalled = 35; remaining_slice_position();
signalled = 36; strerror_cases();
return 0;
};