How to encode HashMap to json stirng?

I want to encode my struct with a HashMap type field to json to save to a file.

const Some = struct {
    some_field: std.AutoHashMap(u64, u64),
};

var some_hash_map = std.AutoHashMap(u64, u64).init(allocator);
try some_hash_map.put(123, 321);

const some = Some{
    .some_field = some_hash_map,
};

const string = try std.json.stringifyAlloc(allocator, some, .{});
std.debug.print("{s}\n", .{string});

When compiling I get these errors:

/home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:552:52: error: cannot load opaque type 'anyopaque'
                            return self.write(value.*);
                                              ~~~~~^~
referenced by:
    write__anon_8312: /home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:533:43
    write__anon_8170: /home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:533:43
    remaining reference traces hidden; use '-freference-trace' to see all reference traces
/home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:557:29: error: unable to stringify type '[*]hash_map.HashMapUnmanaged(u64,u64,hash_map.AutoContext(u64),80).Metadata' without sentinel
                            @compileError("unable to stringify type '" ++ @typeName(T) ++ "' without sentinel");
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:552:52: error: values of type 'fn (*anyopaque, usize, u8, usize) ?[*]u8' must be comptime-known, but operand value is runtime-known
                            return self.write(value.*);
                                              ~~~~~^~
/home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:552:52: note: use '*const fn (*anyopaque, usize, u8, usize) ?[*]u8' for a function pointer type
/home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:552:52: error: values of type 'fn (*anyopaque, []u8, u8, usize, usize) bool' must be comptime-known, but operand value is runtime-known
                            return self.write(value.*);
                                              ~~~~~^~
/home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:552:52: note: use '*const fn (*anyopaque, []u8, u8, usize, usize) bool' for a function pointer type
/home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:552:52: error: values of type 'fn (*anyopaque, []u8, u8, usize) void' must be comptime-known, but operand value is runtime-known
                            return self.write(value.*);
                                              ~~~~~^~
/home/d/zig/zig-0.12.0/lib/std/json/stringify.zig:552:52: note: use '*const fn (*anyopaque, []u8, u8, usize) void' for a function pointer type

I recently started learning this programming language, tried to do something similar and got stuck. How to do it right and make it work?

1 Like

Welcome to ziggit! :slight_smile:

AutoHashMap is a complex data structure that stringify cannot automatically convert it to json.
You can find the supported types here.

Two solutions are:

  1. implement in the Some struct
    pub fn jsonStringify(self: *@This(), jw: anytype) !void
    to stringify to json the way you want.
  2. use json Value to store your data as json values.
2 Likes

Hi sorry for a reply to an old thread, but this solution did not help me because it did not offer an example on how to implement jsonStringify function on some struct.

I found this example which should work for a situation like this

          pub fn jsonStringify(self: @This(), jws: anytype) !void {
              try jws.beginObject();
              var it = self.map.iterator();
              while (it.next()) |kv| {
                  try jws.objectField(kv.key_ptr.*);
                  try jws.write(kv.value_ptr.*);
              }
              try jws.endObject();
          }

there is some more info here
and here are docs to json.WriteStream

3 Likes