fix: use composed enum keys for driver diagnostics (EnumMap)

This commit is contained in:
2026-10-24 03:48:35 +02:00
parent d2cec370fa
commit 9c1bd2a20e
3 changed files with 79 additions and 18 deletions
+16 -18
View File
@@ -50,11 +50,11 @@ main proc(init process.Init) i32 {
return command(mem.c_allocator, init.io, init.args) catch |err| { return command(mem.c_allocator, init.io, init.args) catch |err| {
if (init.args.values.len > 2) { if (init.args.values.len > 2) {
io.print("{s}: infrastructure error: {s}\n", io.stderr(init.io), { io.print("{s}: infrastructure error: {s}\n", io.stderr(init.io), {
init.args.values[2], infrastructure_message(err), init.args.values[2], enummap.get(&infrastructure_messages, err)?,
}) catch |_| {} }) catch |_| {}
} else { } else {
io.print("honey: infrastructure error: {s}\n", io.stderr(init.io), { io.print("honey: infrastructure error: {s}\n", io.stderr(init.io), {
infrastructure_message(err), enummap.get(&infrastructure_messages, err)?,
}) catch |_| {} }) catch |_| {}
} }
return 2 return 2
@@ -62,22 +62,20 @@ main proc(init process.Init) i32 {
} }
@hide:file @hide:file
infrastructure_message proc(error DriverError) []u8 { infrastructure_messages :: $enummap.init(DriverError, []u8, {
return match error { out_of_memory = "out of memory",
.out_of_memory: "out of memory" diagnostic_limit_reached = "diagnostic limit reached",
.diagnostic_limit_reached: "diagnostic limit reached" storage_limit_reached = "aggregate storage limit reached",
.storage_limit_reached: "aggregate storage limit reached" source_too_large = "source file is too large",
.source_too_large: "source file is too large" out_of_space = "identifier storage is full",
.out_of_space: "identifier storage is full" open_failed = "cannot open source file",
.open_failed: "cannot open source file" close_failed = "cannot close source file",
.close_failed: "cannot close source file" not_open_for_reading = "source file is not readable",
.not_open_for_reading: "source file is not readable" read_failed = "cannot read source file",
.read_failed: "cannot read source file" not_open_for_writing = "output is not writable",
.not_open_for_writing: "output is not writable" write_failed = "cannot write output",
.write_failed: "cannot write output" no_progress = "output writer made no progress",
.no_progress: "output writer made no progress" })
}
}
@hide:file @hide:file
command proc(allocator mem.Allocator, runtime io.Io, args process.Args) i32 ! DriverError { command proc(allocator mem.Allocator, runtime io.Io, args process.Args) i32 ! DriverError {
+2
View File
@@ -1,5 +1,7 @@
import "@std/meta" import "@std/meta"
#! keys may be enums or native enum compositions that normalize to an enum, including aliases.
#! shared variant names follow native composition identity; payload-bearing sums are not enum keys.
EnumMap proc($E, $V type) type { EnumMap proc($E, $V type) type {
match typeinfo!(E) { match typeinfo!(E) {
.enum |info|: return struct { .enum |info|: return struct {
+61
View File
@@ -24,3 +24,64 @@ handles_sparse_enum_get test {
try testing.expect_type(?[]u8, eof) try testing.expect_type(?[]u8, eof)
try testing.expect_equal(null, eof) try testing.expect_equal(null, eof)
} }
@hide:file
TestLeftError :: enum {
shared
left
absent_left
}
@hide:file
TestRightError :: enum {
shared
right
absent_right
}
@hide:file
TestNestedError :: alias (TestLeftError | (TestRightError | TestLeftError))
@hide:file
TestComposedError :: alias TestNestedError
@hide:file
composed_values :: $init(TestComposedError, i32, {
shared = 11,
left = 22,
absent_left = 33,
right = 44,
absent_right = 55,
})
handles_composed_enum_keys_at_runtime test {
names EnumMap(TestComposedError, []u8) :: init({
shared = "shared error",
left = "left error",
right = "right error",
})
keys [_]TestComposedError :: [
TestLeftError.shared,
TestLeftError.left,
TestRightError.shared,
TestRightError.right,
TestLeftError.absent_left,
TestRightError.absent_right,
]
expected [_]?[]u8 :: [
"shared error",
"left error",
"shared error",
"right error",
null,
null,
]
expected_values [_]i32 :: [11, 22, 11, 44, 33, 55]
for keys |key, index| {
value :: get(&names, key)
try testing.expect_type(?[]u8, value)
try testing.expect_equal(expected[index], value)
try testing.expect_equal(expected_values[index], get(&composed_values, key)?)
}
}