Skip to content

std.zon.parse: add parsing of enum literals as string #23261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions lib/std/zon/parse.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const valid_types = {};
pub const Options = struct {
/// If true, unknown fields do not error.
ignore_unknown_fields: bool = false,
/// Enables parsing enum literals as `[]const u8`.
enum_literals_as_strings: bool = false,
/// If true, the parser cleans up partially parsed values on error. This requires some extra
/// bookkeeping, so you may want to turn it off if you don't need this feature (e.g. because
/// you're using arena allocation.)
Expand Down Expand Up @@ -616,6 +618,23 @@ const Parser = struct {
.string_literal => return self.parseString(T, node),
.array_literal => |nodes| return self.parseSlice(T, nodes),
.empty_literal => return self.parseSlice(T, .{ .start = node, .len = 0 }),
.enum_literal => |field_name| {
if (!self.options.enum_literals_as_strings) return error.WrongType;
const pointer = @typeInfo(T).pointer;
if (pointer.child != u8 or
pointer.size != .slice or
!pointer.is_const or
(pointer.sentinel() != null and pointer.sentinel() != 0) or
pointer.alignment != 1)
{
return error.WrongType;
}
if (pointer.sentinel()) |_| {
return self.gpa.dupeZ(u8, field_name.get(self.zoir));
} else {
return self.gpa.dupe(u8, field_name.get(self.zoir));
}
},
else => return error.WrongType,
}
}
Expand Down Expand Up @@ -2364,6 +2383,38 @@ test "std.zon enum literals" {
}
}

test "std.zon enums_as_strings" {
const gpa = std.testing.allocator;
// bare literal
{
const parsed = try fromSlice([:0]const u8, gpa, ".my_enum_literal", null, .{
.enum_literals_as_strings = true,
});
defer free(gpa, parsed);
try std.testing.expectEqualStrings(@as([:0]const u8, "my_enum_literal"), parsed);
}
// quoted enum literal with a " special character
{
const parsed = try fromSlice([]const u8, gpa, ".@\"test\\\"\"", null, .{
.enum_literals_as_strings = true,
});
defer free(gpa, parsed);
try std.testing.expectEqualStrings(@as([]const u8, "test\""), parsed);
}
// bare literal in struct
{
const parsed = try fromSlice(struct {
name: []const u8,
type: []const u8,
}, gpa, ".{ .name = .literal_0, .type = .literal_1 }", null, .{
.enum_literals_as_strings = true,
});
defer free(gpa, parsed);
try std.testing.expectEqualStrings(@as([]const u8, "literal_0"), parsed.name);
try std.testing.expectEqualStrings(@as([]const u8, "literal_1"), parsed.type);
}
}

test "std.zon parse bool" {
const gpa = std.testing.allocator;

Expand Down
Loading