Announcing Getty 0.2.0
I am happy to announce a new version of Getty, 0.2.0.
Getty is a framework for building robust, optimal, and reusable serializers/deserializers in Zig. To install Getty, follow the instructions listed on the Installation page.
What's in 0.2.0
Revamped Interfaces
Thanks to stage2, there were lots of improvements made to the interfaces in Getty. Most notably:
- Required method parameters are now optional struct fields, making implementing interfaces much simpler.
- Most associated types have been made optional, so no more
getty.TODO
. - Empty error sets are now allowed.
- No more relying on
undefined
errors to indicate that a unimplemented method was called. Getty can now have@compileError
s in its interfaces to let you know about that.
const Serializer = struct {
pub usingnamespace Serializer(
@This(),
void,
error{},
null,
null,
null,
null,
null,
.{ .serializeBool = serializeBool },
);
};
Simpler Customization
On the customization side of things, two main features have been added.
First, you can now write type-defined blocks/tuples (TBT), which are
(de)serialization blocks/tuples defined within a struct
or union
type.
Getty will automatically process TBTs, meaning that you don't have to pass them
in explicitly.
Second, preliminary support for attributes have landed. Attributes allow
you to easily configure the (de)serialization process for a type without having
to manually write everything out. This release introduced support only for the
skip
, rename
, and ignore_unknown_fields
attributes.
const std = @import("std");
const json = @import("json");
const allocator = std.heap.page_allocator;
const Point = struct {
x: i32,
y: i32,
pub const @"getty.sbt" = struct {
pub fn is(comptime T: type) bool {
return T == Point;
}
pub const attributes = .{
.x = .{ .rename = "X" },
.y = .{ .skip = true },
};
};
};
pub fn main() !void {
_ = try json.toSlice(allocator, Point{ .x = 1, .y = 2 }); // {"X":1}
}
Union Serialization
Before, unions were serialized as their payload value. However, this made things inconsistent as there was no good way to go back during deserialization with that approach.
To fix this, unions are now serialized using the externally tagged format by default.
const std = @import("std");
const getty = @import("getty");
const json = @import("json");
const allocator = std.heap.page_allocator;
pub fn main() !void {
const U = union(enum) { foo: i32 };
var slice = try json.toSlice(allocator, U{ .foo = 123 });
defer allocator.free(slice);
std.debug.print("{s}\n", .{slice}); // {"foo":123}
}
Ignoring Deserialized Data
A new method has been added to the
getty.Deserializer
interface:
deserializeIgnored
. This method is intended to be used whenever the input
data of a deserializer should be ignored. For example, when the skip
attribute is set for a struct
, deserializeIgnored
can be called in order to
ignore a key and/or value in the deserializer's input data.
Support
Some new types are now supported by Getty!
Serialization
Deserialization
- Union (tagged)
- Union (untagged)
- Sentinel-terminated slice
Other Changes
There are other changes in the Getty 0.2.0 release. You can see the full changelog here.