Allow returning default values on base struct

This commit is contained in:
jaina heartles 2022-12-18 05:19:17 -08:00
parent a0b2e22e32
commit e02c5d99e4

View file

@ -266,7 +266,7 @@ pub fn DeserializerContext(comptime Result: type, comptime From: type, comptime
}
pub fn finish(self: *@This(), allocator: std.mem.Allocator) !Result {
return (try self.deserialize(allocator, Result, self.data, &.{})) orelse
return (try self.deserialize(allocator, Result, self.data, &.{}, true)) orelse
if (std.meta.fields(Result).len == 0)
return .{}
else
@ -290,6 +290,7 @@ pub fn DeserializerContext(comptime Result: type, comptime From: type, comptime
comptime T: type,
intermediary: anytype,
comptime field_ref: FieldRef,
allow_default: bool,
) DeserializeError!?T {
if (comptime Context.options.isScalar(T)) {
const val = @field(intermediary.static, util.comptimeJoin(".", field_ref));
@ -304,7 +305,7 @@ pub fn DeserializerContext(comptime Result: type, comptime From: type, comptime
var partial_match_found: bool = false;
inline for (info.fields) |field| {
const F = field.field_type;
const maybe_value = self.deserialize(allocator, F, intermediary, field_ref) catch |err| switch (err) {
const maybe_value = self.deserialize(allocator, F, intermediary, field_ref, false) catch |err| switch (err) {
error.MissingField => blk: {
partial_match_found = true;
break :blk @as(?F, null);
@ -333,7 +334,7 @@ pub fn DeserializerContext(comptime Result: type, comptime From: type, comptime
inline for (info.fields) |field, i| {
const F = field.field_type;
const new_field_ref = field_ref ++ &[_][]const u8{field.name};
const maybe_value = try self.deserialize(allocator, F, intermediary, new_field_ref);
const maybe_value = try self.deserialize(allocator, F, intermediary, new_field_ref, false);
if (maybe_value) |v| {
@field(result, field.name) = v;
fields_alloced[i] = true;
@ -350,7 +351,7 @@ pub fn DeserializerContext(comptime Result: type, comptime From: type, comptime
}
if (any_missing and any_explicit) return error.MissingField;
if (!any_explicit) {
if (!any_explicit and !allow_default) {
inline for (info.fields) |field, i| {
if (fields_alloced[i]) self.deserializeFree(allocator, @field(result, field.name));
}
@ -369,7 +370,7 @@ pub fn DeserializerContext(comptime Result: type, comptime From: type, comptime
var count: usize = 0;
errdefer for (result[0..count]) |res| util.deepFree(allocator, res);
for (data.items) |sub, i| {
result[i] = (try self.deserialize(allocator, info.child, sub, &.{})) orelse return error.SparseSlice;
result[i] = (try self.deserialize(allocator, info.child, sub, &.{}, false)) orelse return error.SparseSlice;
}
return result;
@ -378,7 +379,7 @@ pub fn DeserializerContext(comptime Result: type, comptime From: type, comptime
},
// Specifically non-scalar optionals
.Optional => |info| return try self.deserialize(allocator, info.child, intermediary, field_ref),
.Optional => |info| return try self.deserialize(allocator, info.child, intermediary, field_ref, allow_default),
else => @compileError("Unsupported type"),
}