Closed Cloudef closed 7 months ago
Okay so you can do it like this:
pub const HeaderKv = std.meta.Tuple(&.{ []const u8, []const u8 });
pub const Headers = []const HeaderKv;
const HeadersBlock = struct {
pub fn is(comptime T: type) bool {
return T == Headers;
}
pub fn serialize(_: ?std.mem.Allocator, value: anytype, serializer: anytype) @TypeOf(serializer).Err!@TypeOf(serializer).Ok {
var m = try serializer.serializeMap(value.len);
const map = m.map();
for (value[0..]) |tuple| {
try map.serializeEntry(tuple.@"0", tuple.@"1");
}
return try map.end();
}
pub fn deserialize(ally: ?std.mem.Allocator, comptime T: type, deserializer: anytype, visitor: anytype) @TypeOf(deserializer).Err!@TypeOf(visitor).Value {
_ = T;
return try deserializer.deserializeMap(ally.?, visitor);
}
pub fn Visitor(comptime Value: type) type {
return struct {
pub usingnamespace getty.de.Visitor(
@This(),
Value,
.{ .visitMap = visitMap },
);
pub fn visitMap(_: @This(), ally: std.mem.Allocator, comptime Deserializer: type, map: anytype) Deserializer.Err!Value {
const allocated = 32;
var headers = try ally.alloc(HeaderKv, allocated);
errdefer ally.free(headers);
var len: usize = 0;
while (try map.nextKey(ally, []const u8)) |k| {
if (len >= allocated) return error.InvalidLength;
const v = try map.nextValue(ally, []const u8);
headers[len] = .{ k, v };
len += 1;
}
return headers[0..len];
}
};
}
};
And then you pass this block to getty-json's toSliceWith and fromSliceWith methods. Leaving this here as a reference.
Problem
As far as I see currently deser of maps requires a std type.
Consider type:
const Headers = []const std.meta.Tuple(&.{ []const u8, []const u8 });
With getty-json, this serializes to array of arrays:
[["a","b"],["c", "d"]]
Proposal
It would be nice you could control the behavior so that the tuple is used as
key: value
instead.[{"a":"b"},{"c":"d"}]
Is there currently way to do this?
Additional Context
No response