From 8aaceba4845bcb433a9a93a2cb4e33d603144658 Mon Sep 17 00:00:00 2001 From: torque Date: Tue, 18 Jun 2024 18:32:16 -0700 Subject: [PATCH] parser.value.convertTo: add field converter concept It is convenient to be able to have custom logic for a specific field on a given struct without having to write a function to manually reify the whole thing from scratch. --- src/parser/value.zig | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/parser/value.zig b/src/parser/value.zig index 9fd5603..0919771 100644 --- a/src/parser/value.zig +++ b/src/parser/value.zig @@ -68,6 +68,10 @@ pub const Value = union(enum) { map: Map, inline_map: Map, + pub fn FieldConverter(comptime T: type) type { + return *const fn (Value, std.mem.Allocator, Options) error{BadValue}!T; + } + pub fn convertTo(self: Value, comptime T: type, allocator: std.mem.Allocator, options: Options) !T { switch (@typeInfo(T)) { .Void => { @@ -215,7 +219,11 @@ pub const Value = union(enum) { var use_count: usize = 0; inline for (stt.fields) |field| { if (map.get(field.name)) |val| { - @field(result, field.name) = try val.convertTo(field.type, allocator, options); + if (comptime hasFn(T, "niceFieldConverter") and T.niceFieldConverter(field.name) != null) { + @field(result, field.name) = try T.niceFieldConverter(field.name).?(val, allocator, options); + } else { + @field(result, field.name) = try val.convertTo(field.type, allocator, options); + } use_count += 1; } else if (options.allow_omitting_default_values) { if (comptime field.default_value) |def|