parser.value.convertTo: simplify struct field usage

This avoids having to clone the map while maintaining the same
conversion strictness.
This commit is contained in:
torque 2024-06-18 18:30:27 -07:00
parent 8ccb2c3a66
commit c74d615131
Signed by: torque
SSH Key Fingerprint: SHA256:nCrXefBNo6EbjNSQhv0nXmEg/VuNq3sMF5b8zETw3Tk

View File

@ -209,39 +209,24 @@ pub const Value = union(enum) {
.map, .inline_map => |map| { .map, .inline_map => |map| {
var result: T = undefined; var result: T = undefined;
if (options.ignore_extra_fields) { if (!options.ignore_extra_fields and (map.count() > stt.fields.len))
inline for (stt.fields) |field| { return error.BadValue;
if (map.get(field.name)) |value| {
@field(result, field.name) = try value.convertTo(field.type, allocator, options); var use_count: usize = 0;
} else if (options.allow_omitting_default_values) { inline for (stt.fields) |field| {
if (comptime field.default_value) |def| if (map.get(field.name)) |val| {
@field(result, field.name) = @as(*align(1) const field.type, @ptrCast(def)).* @field(result, field.name) = try val.convertTo(field.type, allocator, options);
else use_count += 1;
return error.BadValue; } else if (options.allow_omitting_default_values) {
} else { if (comptime field.default_value) |def|
@field(result, field.name) = @as(*align(1) const field.type, @ptrCast(def)).*
else
return error.BadValue; return error.BadValue;
} } else return error.BadValue;
}
} else {
// TODO: consider not cloning the map here. This would
// result in the requirement that the raw value object
// not be used after it has been converted to a type,
// based on the parse options.
var clone = try map.clone();
defer clone.deinit();
inline for (stt.fields) |field| {
if (clone.fetchSwapRemove(field.name)) |kv| {
@field(result, field.name) = try kv.value.convertTo(field.type, allocator, options);
} else if (options.allow_omitting_default_values) {
if (comptime field.default_value) |def|
@field(result, field.name) = @as(*align(1) const field.type, @ptrCast(def)).*
else
return error.BadValue;
} else return error.BadValue;
}
// there were extra fields in the data
if (clone.count() > 0) return error.BadValue;
} }
// there were extra fields in the data
if (!options.ignore_extra_fields and (map.count() > use_count))
return error.BadValue;
return result; return result;
}, },