getty-zig / getty

A (de)serialization framework for Zig
https://getty.so
MIT License
183 stars 14 forks source link

Cannot deserialize into an untagged union pointer #117

Closed ibokuri closed 11 months ago

ibokuri commented 1 year ago

Description

Deserializing into a pointer to an untagged union (i.e., a union with the tag attribute set to .untagged) raises a type mismatch compile error.

How to Reproduce the Bug

const std = @import("std");
const json = @import("json");

const ally = std.heap.page_allocator;

const Union = union(enum) {
    foo: i32,
    bar: bool,

    pub const @"getty.db" = struct {
        pub const attributes = .{
            .Container = .{ .tag = .untagged },
        };
    };
};

pub fn main() !void {
    const u = try json.fromSlice(ally, *Union, "1");
    std.debug.print("{}\n", .{u.*});
}
$ zig build -freference-trace run
zig build-exe quick-start Debug native: error: the following command failed with 1 compilation errors:
/Users/jason/.asdf/installs/zig/master/zig build-exe -freference-trace=256 /Users/jason/Projects/Personal/test/src/main.zig --cache-dir /Users/jason/Projects/Personal/test/zig-cache --global-cache-dir /Users/jason/.cache/zig --name quick-start --mod getty::/Users/jason/.cache/zig/p/12205aae2ea6dcaa3efcf3751c40dbd3946e539794688bad62e79c86635762204a3d/src/getty.zig --mod concepts::/Users/jason/.cache/zig/p/12204cbd628c6436be2c90d1e4b782a00be121133de83b0cdd800a2777dc1e1aee84/src/lib.zig --mod json:getty,concepts:/Users/jason/.cache/zig/p/1220465f43808ceff290a3473a63fe623d2bf9c9968de242af188930ec5301a17de4/src/json.zig --deps getty,json --listen=-
Build Summary: 0/3 steps succeeded; 1 failed (disable with --summary none)
run transitive failure
└─ run quick-start transitive failure
   └─ zig build-exe quick-start Debug native 1 errors
/Users/jason/.cache/zig/p/12205aae2ea6dcaa3efcf3751c40dbd3946e539794688bad62e79c86635762204a3d/src/de/blocks/union.zig:94:20: error: expected type 'error{OutOfMemory,DuplicateField,InvalidLength,InvalidType,InvalidValue,MissingAllocator,MissingField,MissingVariant,UnknownField,UnknownVariant,Unsupported,SyntaxError,UnexpectedEndOfInput,ValueTooLong,Overflow,InvalidCharacter}!*main.Union', found 'main.Union'
            return @unionInit(T, field.name, value);
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.zig:6:15: note: union declared here
const Union = union(enum) {
              ^~~~~
/Users/jason/.cache/zig/p/12205aae2ea6dcaa3efcf3751c40dbd3946e539794688bad62e79c86635762204a3d/src/de/blocks/union.zig:71:30: note: function return type declared here
) @TypeOf(deserializer).Error!@TypeOf(visitor).Value {
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    deserialize__anon_4476: /Users/jason/.cache/zig/p/12205aae2ea6dcaa3efcf3751c40dbd3946e539794688bad62e79c86635762204a3d/src/de/blocks/union.zig:52:26
    deserialize__anon_4342: /Users/jason/.cache/zig/p/12205aae2ea6dcaa3efcf3751c40dbd3946e539794688bad62e79c86635762204a3d/src/de/blocks/pointer.zig:45:46
    deserialize__anon_2774: /Users/jason/.cache/zig/p/12205aae2ea6dcaa3efcf3751c40dbd3946e539794688bad62e79c86635762204a3d/src/de/deserialize.zig:41:18
    fromDeserializer__anon_2740: /Users/jason/.cache/zig/p/1220465f43808ceff290a3473a63fe623d2bf9c9968de242af188930ec5301a17de4/src/de.zig:32:28
    fromReaderWith__anon_2252: /Users/jason/.cache/zig/p/1220465f43808ceff290a3473a63fe623d2bf9c9968de242af188930ec5301a17de4/src/de.zig:43:16
    fromSliceWith__anon_2141: /Users/jason/.cache/zig/p/1220465f43808ceff290a3473a63fe623d2bf9c9968de242af188930ec5301a17de4/src/de.zig:53:16
    fromSlice__anon_2139: /Users/jason/.cache/zig/p/1220465f43808ceff290a3473a63fe623d2bf9c9968de242af188930ec5301a17de4/src/de.zig:58:16
    main: src/main.zig:18:23
    callMain: /Users/jason/.asdf/installs/zig/master/lib/std/start.zig:608:32
    initEventLoopAndCallMain: /Users/jason/.asdf/installs/zig/master/lib/std/start.zig:542:34
    callMainWithArgs: /Users/jason/.asdf/installs/zig/master/lib/std/start.zig:492:12
    main: /Users/jason/.asdf/installs/zig/master/lib/std/start.zig:507:34

Additional Context

No response

ibokuri commented 1 year ago

The problem is that in deserializeUntaggedUnion, @unionInit is returned from the function directly. Instead of doing that, we need to use the visitor parameter passed to the function by Getty.

The issue there is I'm not exactly sure how to do that properly...