parser: change omitted value behavior to work with all default values
Special casing optional values was a little odd before. Now, the user can supply a default value for any field that may be omitted from the serialized data. This behaves the same way as the stdlib JSON parser as well.
This commit is contained in:
parent
e8ddee5ab2
commit
21a9753d46
@ -61,11 +61,11 @@ pub const Options = struct {
|
||||
ignore_extra_fields: bool = true,
|
||||
|
||||
// Only used by the parseTo family of functions.
|
||||
// If true, if a struct field is an optional type and the corresponding mapping key
|
||||
// does not exist, the object field will be set to `null`. By default, if the
|
||||
// parsed document is missing a mapping key for a given field, an error will be
|
||||
// raised instead.
|
||||
treat_omitted_as_null: bool = false,
|
||||
// If true, if a struct field has a default value associated with it and the
|
||||
// corresponding mapping key does not exist, the object field will be set to the
|
||||
// default value. By default, this behavior is enabled, allowing succinct
|
||||
// representation of objects that have default fields.
|
||||
allow_omitting_default_values: bool = true,
|
||||
|
||||
// Only used by the parseTo family of functions.
|
||||
// If true, strings may be coerced into other scalar types, like booleans or
|
||||
|
@ -208,8 +208,11 @@ pub const Value = union(enum) {
|
||||
inline for (stt.fields) |field| {
|
||||
if (map.get(field.name)) |value| {
|
||||
@field(result, field.name) = try value.convertTo(field.type, allocator, options);
|
||||
} else if (options.treat_omitted_as_null and @typeInfo(field.type) == .Optional) {
|
||||
@field(result, field.name) = null;
|
||||
} 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;
|
||||
}
|
||||
@ -224,8 +227,11 @@ pub const Value = union(enum) {
|
||||
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.treat_omitted_as_null and @typeInfo(field.type) == .Optional) {
|
||||
@field(result, field.name) = null;
|
||||
} 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user