Ziggy help: error unexpected, parsing a simple zgy file

Using ziggy to parse a simple file
config.zgy

{
	.heartbeat = "1s",
}

config struct used to parse the zgy file

pub const Config = struct {
    heartbeat: []const u8,
};

below is the function, which reads the file and uses ziggy. Based on new update from ziggy the function is using deserializeLeaky as the allocation passed is a arena allocator.

pub fn read_config(io: std.Io, file_name: []const u8, allocator: std.mem.Allocator) !Config {
    const data = try read.read_file(io, file_name, allocator);
    var meta: ziggy.Deserializer.Meta = .init;
    const file_data: [:0]u8 = @ptrCast(data);
    print("data from file: {s}\n", .{file_data});
    const cfg = try ziggy.deserializeLeaky(Config, allocator, file_data, &meta, .{});
    return cfg;
}

error message received is below. The part where code reads the file works as expected. Validated from print statement in fn. Not sure what is the issue, need help with parsing error error: Unexpected

zig build run                       
data from file: {
        .heartbeat = "1s",
}

error: Unexpected
/home/karthick/.cache/zig/p/ziggy-0.1.0-kTg8vwR1BgALu5bIsNMQrQ2h2tpD8P-8Ax-1WjLU3Cuf/src/Deserializer.zig:180:5: 0x1189e47 in unexpected (root.zig)
    return error.Unexpected;
    ^
/home/karthick/.cache/zig/p/ziggy-0.1.0-kTg8vwR1BgALu5bIsNMQrQ2h2tpD8P-8Ax-1WjLU3Cuf/src/Deserializer.zig:463:24: 0x117cd6b in deserializeOne__anon_27301 (root.zig)
                .lb => return d.deserializeDict(T, &result, info, &seen, first),
                       ^
/home/karthick/.cache/zig/p/ziggy-0.1.0-kTg8vwR1BgALu5bIsNMQrQ2h2tpD8P-8Ax-1WjLU3Cuf/src/Deserializer.zig:261:20: 0x11697aa in deserializeLeaky__anon_26867 (root.zig)
    const result = try d.deserializeOne(T, tokenizer.next(src, true), true);
                   ^
/home/karthick/projects/memcache/coordinator/src/config.zig:15:17: 0x1166813 in read_config (main.zig)
    const cfg = try ziggy.deserializeLeaky(Config, allocator, file_data, &meta, .{});

You cannot cast like that. The library expects an actual zero terminator in the data.
You can allocate the file_size + 1 and add a trailing zero after the file contents.

Also remove the braces from the file, leaving it as:

.heartbeat = "1s",

A working example is:

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

pub const Config = struct {
    heartbeat: []const u8,
};

pub fn main() !void {
    var gpa: std.heap.DebugAllocator(.{}) = .init;
    defer _ = gpa.deinit();

    var arena: std.heap.ArenaAllocator = .init(gpa.allocator());
    defer arena.deinit();
    const file_data: [:0]const u8 =
        \\.heartbeat = "1s",
    ;
    var meta: ziggy.Deserializer.Meta = .init;
    const cfg = try ziggy.deserializeLeaky(Config, arena.allocator(), file_data, &meta, .{});
    std.debug.print("heartbeat={s}\n", .{cfg.heartbeat});
}
1 Like

thanks, i tried unfortunately when i tried by reading file still getting error.

const std = @import("std");
const ziggy = @import("ziggy");
// const zig_json = @import("zig_json");
const Config = struct {
    heart_beat: []u8,
};

pub fn main() !void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    var thread = std.Io.Threaded.init(arena.allocator());
    defer thread.deinit();
    // const buf = try arena.allocator().alloc(u8, 1096);
    // const data = try std.Io.Dir.cwd().readFile(thread.ioBasic(), "data.json", buf);
    // const cfg: Config = try std.json.parseFromSliceLeaky(Config, arena.allocator(), @ptrCast(data), .{});
    // std.debug.print("data:{s}\n", .{cfg.heart_beat});
    std.debug.print("+++++++++++++\n", .{});
    const dir = std.Io.Dir.cwd();
    const file = try std.Io.Dir.openFile(dir, thread.ioBasic(), "config.zgy", .{});
    const stat = try file.stat(thread.ioBasic());
    std.debug.print("file size:{d}\n", .{stat.size});
    const buffer = try arena.allocator().alloc(u8, stat.size + 1);
    std.debug.print("size:{d}\n", .{buffer.len});
    var meta: ziggy.Deserializer.Meta = .init;
    const file_data = try std.Io.Dir.readFile(dir, thread.ioBasic(), "config.zgy", buffer);
    const buf: [:0]const u8 = @ptrCast(file_data);
    // // const f_data: [:0]const u8 = @ptrCast(&file_data);
    const cfg_zgy: Config = try ziggy.deserializeLeaky(Config, arena.allocator(), buf, &meta, .{});
    std.debug.print("data:{s}\n", .{cfg_zgy.heart_beat});
}

error:

file size:20
size:21
error: UnknownField
/home/karthick/.cache/zig/p/ziggy-0.1.0-kTg8vwR1BgALu5bIsNMQrQ2h2tpD8P-8Ax-1WjLU3Cuf/src/Deserializer.zig:208:5: 0x1161f57 in unknownField (root.zig)
    return error.UnknownField;

from error i can infer the total file size is 20 and allocated buffer is 21. i.e - 1 last place is empty.
updated the file as well as per the corrected version

.heartbeat = "1s",

You have a typo in your file: in your Config struct, you’re expecting heart_beat, but in your Ziggy file, you have heartbeat (no underscore).