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,
|
ignore_extra_fields: bool = true,
|
||||||
|
|
||||||
// Only used by the parseTo family of functions.
|
// Only used by the parseTo family of functions.
|
||||||
// If true, if a struct field is an optional type and the corresponding mapping key
|
// If true, if a struct field has a default value associated with it and the
|
||||||
// does not exist, the object field will be set to `null`. By default, if the
|
// corresponding mapping key does not exist, the object field will be set to the
|
||||||
// parsed document is missing a mapping key for a given field, an error will be
|
// default value. By default, this behavior is enabled, allowing succinct
|
||||||
// raised instead.
|
// representation of objects that have default fields.
|
||||||
treat_omitted_as_null: bool = false,
|
allow_omitting_default_values: bool = true,
|
||||||
|
|
||||||
// Only used by the parseTo family of functions.
|
// Only used by the parseTo family of functions.
|
||||||
// If true, strings may be coerced into other scalar types, like booleans or
|
// 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| {
|
inline for (stt.fields) |field| {
|
||||||
if (map.get(field.name)) |value| {
|
if (map.get(field.name)) |value| {
|
||||||
@field(result, field.name) = try value.convertTo(field.type, allocator, options);
|
@field(result, field.name) = try value.convertTo(field.type, allocator, options);
|
||||||
} else if (options.treat_omitted_as_null and @typeInfo(field.type) == .Optional) {
|
} else if (options.allow_omitting_default_values) {
|
||||||
@field(result, field.name) = null;
|
if (comptime field.default_value) |def|
|
||||||
|
@field(result, field.name) = @as(*align(1) const field.type, @ptrCast(def)).*
|
||||||
|
else
|
||||||
|
return error.BadValue;
|
||||||
} else {
|
} else {
|
||||||
return error.BadValue;
|
return error.BadValue;
|
||||||
}
|
}
|
||||||
@ -224,8 +227,11 @@ pub const Value = union(enum) {
|
|||||||
inline for (stt.fields) |field| {
|
inline for (stt.fields) |field| {
|
||||||
if (clone.fetchSwapRemove(field.name)) |kv| {
|
if (clone.fetchSwapRemove(field.name)) |kv| {
|
||||||
@field(result, field.name) = try kv.value.convertTo(field.type, allocator, options);
|
@field(result, field.name) = try kv.value.convertTo(field.type, allocator, options);
|
||||||
} else if (options.treat_omitted_as_null and @typeInfo(field.type) == .Optional) {
|
} else if (options.allow_omitting_default_values) {
|
||||||
@field(result, field.name) = null;
|
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;
|
} else return error.BadValue;
|
||||||
}
|
}
|
||||||
// there were extra fields in the data
|
// there were extra fields in the data
|
||||||
|
Loading…
x
Reference in New Issue
Block a user