From 1673022fa6c100afe6309e55259addf6e19aa8d0 Mon Sep 17 00:00:00 2001 From: pfg Date: Wed, 28 Aug 2024 00:47:36 -0700 Subject: [PATCH 1/2] Support stringifying non-exhaustive enum to json --- lib/std/json/stringify.zig | 17 ++++++++++++++++- lib/std/json/stringify_test.zig | 9 +++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/std/json/stringify.zig b/lib/std/json/stringify.zig index 965b7c3113c9..2fdfc671452f 100644 --- a/lib/std/json/stringify.zig +++ b/lib/std/json/stringify.zig @@ -540,11 +540,26 @@ pub fn WriteStream( return try self.write(null); } }, - .Enum, .EnumLiteral => { + .Enum => |enum_info| { if (std.meta.hasFn(T, "jsonStringify")) { return value.jsonStringify(self); } + if (!enum_info.is_exhaustive) { + inline for (enum_info.fields) |field| { + if (value == @field(T, field.name)) { + break; + } + } else { + try self.valueStart(); + try self.stream.print("{d}", .{@intFromEnum(value)}); + return self.valueDone(); + } + } + + return self.stringValue(@tagName(value)); + }, + .EnumLiteral => { return self.stringValue(@tagName(value)); }, .Union => { diff --git a/lib/std/json/stringify_test.zig b/lib/std/json/stringify_test.zig index c0003b87dcc5..52e38d1e30ad 100644 --- a/lib/std/json/stringify_test.zig +++ b/lib/std/json/stringify_test.zig @@ -172,6 +172,15 @@ test "stringify enums" { try testStringify("\"bar\"", E.bar, .{}); } +test "stringify non-exhaustive enum" { + const E = enum(u8) { + foo = 0, + _, + }; + try testStringify("\"foo\"", E.foo, .{}); + try testStringify("1", @as(E, @enumFromInt(1)), .{}); +} + test "stringify enum literals" { try testStringify("\"foo\"", .foo, .{}); try testStringify("\"bar\"", .bar, .{}); From c64ca0a7d0672f1e10539baef93e42b9316a5451 Mon Sep 17 00:00:00 2001 From: pfg Date: Sat, 7 Sep 2024 00:19:22 -0400 Subject: [PATCH 2/2] Add documentation and use a recursive call rather than calling write directly --- lib/std/json/stringify.zig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/std/json/stringify.zig b/lib/std/json/stringify.zig index 2fdfc671452f..d568f01c6ef6 100644 --- a/lib/std/json/stringify.zig +++ b/lib/std/json/stringify.zig @@ -483,6 +483,7 @@ pub fn WriteStream( /// * If the union declares a method `pub fn jsonStringify(self: *@This(), jw: anytype) !void`, it is called to do the serialization instead of the default behavior. The given `jw` is a pointer to this `WriteStream`. /// * Zig `enum` -> JSON string naming the active tag. /// * If the enum declares a method `pub fn jsonStringify(self: *@This(), jw: anytype) !void`, it is called to do the serialization instead of the default behavior. The given `jw` is a pointer to this `WriteStream`. + /// * If the enum is non-exhaustive, unnamed values are rendered as integers. /// * Zig untyped enum literal -> JSON string naming the active tag. /// * Zig error -> JSON string naming the error. /// * Zig `*T` -> the rendering of `T`. Note there is no guard against circular-reference infinite recursion. @@ -551,9 +552,7 @@ pub fn WriteStream( break; } } else { - try self.valueStart(); - try self.stream.print("{d}", .{@intFromEnum(value)}); - return self.valueDone(); + return self.write(@intFromEnum(value)); } }