Default Values and Optional Fields
It’s common for schema languages to let users express the concept that a given set of struct fields can be omitted in a document. This is a concept that intertwines with default values as usually it’s fields for which users define a default value that can be omitted.
In the case of Ziggy Schema there is no way to specify the default value of a struct field, but there is nevertheless a way to omit fields.
Omissible struct fields
In Ziggy Schema a struct field can be omitted if its outermost type is one of:
?(optional)[](slice){:}(dictionary)
In Ziggy Schema semantics these fields are all omissible and expected to respectively default to the following Ziggy Document values:
null(null value)[](empty slice){}(empty dictionary)
As an example, consider the following Ziggy Schema:
$ = MyStruct
struct MyStruct {
enabled: bool,
title: ?bytes,
numbers: []int,
meta: {:}any,
}
Both these Ziggy Documents are compatible with it:
.enabled = true,
.enabled = true,
.title = null, // equivalent to omitting the field
.numbers = [], // equivalent to omitting the field
.meta = {}, // equivalent to omitting the field
Programming Language Type <> Schema compatibility
The Zig implementation of Ziggy includes a build-time function that can be used in a build.zig script to val.author = “”, .date compatibility between a Zig type decl and a Ziggy Schema.
While it might not be possible to implement the same system for all other languages, Ziggy users should expect tooling to support the following behavior:
An omitted struct field of optional, slice, or dict outer type, must correctly deserialize as the struct’s/object’s field default value.
An optional struct field must be able to be deserialized into a an equivalent non-optional struct/object field if that field has a default value (in which case
nullneeds to be deserialized as the field’s default value).
For example the following Zig struct definitions are compatible with the Ziggy Schema from before:
pub const MyStruct = struct {
enabled: bool,
title: ?[]const u8 = null, // <-- natural mapping
numbers: []const usize = &.{},
meta: ziggy.Dictionary = .empty,
};
pub const MyStruct = struct {
enabled: bool,
title: []const u8 = "(empty title)", // <-- also ok
tags: []const usize = &.{},
meta: ziggy.Dictionary = .empty,
};