~alva/zig-bare

7f72ca0d5422d930906957b14be5926855f3d264 — Alva 4 months ago f2ebb76
Be more duck-typed with hashmaps

Also panic on malformed unions.
1 files changed, 27 insertions(+), 5 deletions(-)

M src/bare.zig
M src/bare.zig => src/bare.zig +27 -5
@@ 156,7 156,7 @@ pub const Reader = struct {
            }
        }

        unreachable;
        @panic("malformed union");
    }

    fn readPointer(self: *Self, comptime T: type, stream: var) !T {


@@ 187,11 187,12 @@ pub const Reader = struct {

        var i = try self.readVarUint(stream);
        var map = std.AutoHashMap(K, V).init(&self.arena.allocator);
        try map.ensureCapacity(i);

        while (i != 0) : (i -= 1) {
            const key = try self.read(K, stream);
            const val = try self.read(V, stream);
            _ = try map.put(key, val);
            _ = map.putAssumeCapacity(key, val);
        }

        return map;


@@ 205,6 206,8 @@ pub const Writer = struct {
        return .{};
    }

    pub fn deinit(self: *Self) void {}

    pub fn write(self: *Self, value: var, stream: var) !void {
        const T = @TypeOf(value);
        return switch (@typeInfo(T)) {


@@ 338,15 341,34 @@ pub const Writer = struct {

// Horrible hack.
fn isHashMap(comptime T: type) bool {
    return comptime mem.startsWith(u8, @typeName(T), "std.hash_map.HashMap");
    // These are the only parts of the HashMap API that are used.
    // `HashMapKeyType` and `HashMapValueType` add further constraints.
    return @hasDecl(T, "iterator")
        and @hasDecl(T, "putAssumeCapacity")
        and @hasDecl(T, "ensureCapacity");
}

fn HashMapKeyType(comptime T: type) type {
    return @typeInfo(T.KV).Struct.fields[0].field_type;
    return HashMapType(T, "key");
}

fn HashMapValueType(comptime T: type) type {
    return @typeInfo(T.KV).Struct.fields[1].field_type;
    return HashMapType(T, "value");
}

fn HashMapType(comptime T: type, field_name: []const u8) type {
    const fields = blk: {
        if (@hasDecl(T, "KV")) {
            break :blk @typeInfo(T.KV).Struct.fields;
        } else if (@hasDecl(T, "Entry")) {
            break :blk @typeInfo(T.Entry).Struct.fields;
        } else
            @compileError("unsupported Zig version");
    };

    inline for (fields) |f|
        if (comptime mem.eql(u8, f.name, field_name))
            return f.field_type;
}

fn isValidHashMapKeyType(comptime T: type) bool {