std.zon.parse: parse of enum literals as strings

std.zon: rename enum_literals_as_strings

Co-authored-by: Mason Remaley <MasonRemaley@users.noreply.github.com>

format embedded zon

move down new tests to enum tests
This commit is contained in:
Tobias Simetsreiter 2025-03-15 21:02:53 +01:00
parent 6b4f57a257
commit 28b3042f9e

View file

@ -28,6 +28,8 @@ const valid_types = {};
pub const Options = struct { pub const Options = struct {
/// If true, unknown fields do not error. /// If true, unknown fields do not error.
ignore_unknown_fields: bool = false, 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 /// 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 /// bookkeeping, so you may want to turn it off if you don't need this feature (e.g. because
/// you're using arena allocation.) /// you're using arena allocation.)
@ -690,6 +692,23 @@ const Parser = struct {
.string_literal => return self.parseString(T, node), .string_literal => return self.parseString(T, node),
.array_literal => |nodes| return self.parseSlice(T, nodes), .array_literal => |nodes| return self.parseSlice(T, nodes),
.empty_literal => return self.parseSlice(T, .{ .start = node, .len = 0 }), .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, else => return error.WrongType,
} }
} }
@ -2413,6 +2432,38 @@ test "std.zon enum literals" {
} }
} }
test "std.zon enums_as_strings" {
const gpa = std.testing.allocator;
// bare literal
{
const parsed = try fromSliceAlloc([: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 fromSliceAlloc([]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 fromSliceAlloc(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" { test "std.zon parse bool" {
const gpa = std.testing.allocator; const gpa = std.testing.allocator;