~alva/zig-bare

3c52adee73464ea408f8027ee5abbdabbb37cf8e — Alva 4 months ago b1561f5
zig fmt
3 files changed, 51 insertions(+), 82 deletions(-)

M build.zig
M src/bare.zig
M src/test.zig
M build.zig => build.zig +1 -1
@@ 15,7 15,7 @@ pub fn build(b: *Builder) !void {
    lib.setBuildMode(mode);
    lib.install();
    exe.setBuildMode(mode);
//    exe.linkLibrary(lib);
    //    exe.linkLibrary(lib);
    exe.single_threaded = true;
    exe.link_function_sections = true;
    exe.install();

M src/bare.zig => src/bare.zig +14 -18
@@ 7,9 7,7 @@ const mem = std.mem;
const meta = std.meta;
const warn = std.debug.warn;

pub const ReadError = error {
    Overflow,
};
pub const ReadError = error{Overflow};

pub const Reader = struct {
    arena: std.heap.ArenaAllocator,


@@ 30,11 28,10 @@ pub const Reader = struct {
            .Int => self.readInt(T, stream),
            .Float => self.readFloat(T, stream),
            .Bool => self.readBool(stream),
            .Struct =>
                if (comptime isHashMap(T))
                    self.readHashMap(T, stream)
                else
                    self.readStruct(T, stream),
            .Struct => if (comptime isHashMap(T))
                self.readHashMap(T, stream)
            else
                self.readStruct(T, stream),
            .Enum => self.readEnum(T, stream),
            .Optional => self.readOptional(T, stream),
            .Array => self.readArray(T, stream),


@@ 70,7 67,7 @@ pub const Reader = struct {
            const b = try stream.readByte();

            if (b < 0x80) {
    //            if (9 < i or i == 9 and 1 < b)
                //            if (9 < i or i == 9 and 1 < b)
                if (i == 9 and 1 < b)
                    return ReadError.Overflow;



@@ 221,11 218,10 @@ pub const Writer = struct {
            .Int => self.writeInt(T, value, stream),
            .Float => self.writeFloat(T, value, stream),
            .Bool => self.writeBool(value, stream),
            .Struct =>
                if (comptime isHashMap(T))
                    self.writeHashMap(value, stream)
                else
                    self.writeStruct(value, stream),
            .Struct => if (comptime isHashMap(T))
                self.writeHashMap(value, stream)
            else
                self.writeStruct(value, stream),
            .Enum => self.writeEnum(value, stream),
            .Optional => self.writeOptional(value, stream),
            .Array => self.writeArray(value, stream),


@@ 362,9 358,9 @@ pub const Writer = struct {
fn isHashMap(comptime T: type) bool {
    // 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");
    const has1 = @hasDecl(T, "iterator") or @hasDecl(T, "items");
    const has2 = @hasDecl(T, "putAssumeCapacity") and @hasDecl(T, "ensureCapacity");
    return has1 and has2;
}

fn HashMapKeyType(comptime T: type) type {


@@ 375,7 371,7 @@ fn HashMapValueType(comptime T: type) type {
    return HashMapType(T, "value");
}

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

M src/test.zig => src/test.zig +36 -63
@@ 19,25 19,21 @@ const warn = std.debug.warn;
// TODO: Test that expected compile errors actually result in compile errors.

test "read variable uint" {
    const x = try Reader.init(testing.allocator)
        .readVarUint(io.fixedBufferStream("\x2a").inStream());
    const x = try Reader.init(testing.allocator).readVarUint(io.fixedBufferStream("\x2a").inStream());
    expectEqual(x, 42);
    const y = try Reader.init(testing.allocator)
        .readVarUint(io.fixedBufferStream("\x80\x02").inStream());
    const y = try Reader.init(testing.allocator).readVarUint(io.fixedBufferStream("\x80\x02").inStream());
    expectEqual(y, 0x100);
}

test "read variable uint overflow 1" {
    const buf = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02";
    const x = Reader.init(testing.allocator)
        .readVarUint(io.fixedBufferStream(buf).inStream());
    const x = Reader.init(testing.allocator).readVarUint(io.fixedBufferStream(buf).inStream());
    expectError(ReadError.Overflow, x);
}

test "read variable uint overflow 2" {
    const buf = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00";
    const x = Reader.init(testing.allocator)
        .readVarUint(io.fixedBufferStream(buf).inStream());
    const x = Reader.init(testing.allocator).readVarUint(io.fixedBufferStream(buf).inStream());
    expectError(ReadError.Overflow, x);
}



@@ 62,8 58,7 @@ test "read struct 1" {
        c: bool,
    };

    const res = try Reader.init(testing.allocator)
        .read(Foo, io.fixedBufferStream("\x00\x00\x28\x42\x2a\xaa").inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x00\x00\x28\x42\x2a\xaa").inStream());
    expectEqual(res.a, 42.0);
    expectEqual(res.b, 42);
    expectEqual(res.c, true);


@@ 76,8 71,7 @@ test "read struct 2" {
        c: bool,
    };

    const res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\x00\x00\x28\x42\x2a\x00").inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x00\x00\x28\x42\x2a\x00").inStream());
    expectEqual(res.a, 42.0);
    expectEqual(res.b, 42);
    expectEqual(res.c, false);


@@ 90,8 84,7 @@ test "read struct 3" {
        c: bool,
    };

    const res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\x00\x00\x28\x42\x2b\x00").inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x00\x00\x28\x42\x2b\x00").inStream());
    expectEqual(res.a, 42.0);
    expectEqual(res.b, 43);
    expectEqual(res.c, false);


@@ 104,8 97,7 @@ test "read struct 4" {
        c: bool,
    };

    const res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\x00\x00\x29\x42\x2b\x00").inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x00\x00\x29\x42\x2b\x00").inStream());
    expectEqual(res.a, 42.25);
    expectEqual(res.b, 43);
    expectEqual(res.c, false);


@@ 118,8 110,7 @@ test "read struct 5" {
        c: bool,
    };

    const res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\x00\x00\x00\x00\x00\x00").inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x00\x00\x00\x00\x00\x00").inStream());
    expectEqual(res.a, 0.0);
    expectEqual(res.b, 0);
    expectEqual(res.c, false);


@@ 132,8 123,7 @@ test "read struct 6" {
        c: bool,
    };

    const res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\xff\xff\xff\xff\xff\xff").inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\xff\xff\xff\xff\xff\xff").inStream());
    expect(math.isNan(res.a));
    expectEqual(res.b, 255);
    expectEqual(res.c, true);


@@ 144,50 134,46 @@ test "read struct with void members" {
}

test "read enum" {
    const Foo = enum { a = 2, b = 1, c = 0, };
    var res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\x02").inStream());
    const Foo = enum {
        a = 2,
        b = 1,
        c = 0,
    };
    var res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x02").inStream());
    expectEqual(res, .a);

    res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\x01").inStream());
    res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x01").inStream());
    expectEqual(res, .b);

    res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\x00").inStream());
    res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x00").inStream());
    expectEqual(res, .c);
}

test "read optional u8 value" {
    const res = try Reader.init(testing.allocator).read(?u8,
        io.fixedBufferStream("\x01\x2a").inStream());
    const res = try Reader.init(testing.allocator).read(?u8, io.fixedBufferStream("\x01\x2a").inStream());
    expectEqual(res, 42);
}

test "read optional u8 null" {
    const res = try Reader.init(testing.allocator).read(?u8,
        io.fixedBufferStream("\x00").inStream());
    const res = try Reader.init(testing.allocator).read(?u8, io.fixedBufferStream("\x00").inStream());
    expectEqual(res, null);
}

test "read u8 array" {
    const res = try Reader.init(testing.allocator).read([4]u8,
        io.fixedBufferStream("\x01\x02\x03\x04").inStream());
    const res = try Reader.init(testing.allocator).read([4]u8, io.fixedBufferStream("\x01\x02\x03\x04").inStream());
    const expected = [4]u8{ 1, 2, 3, 4 };
    expectEqual(res, expected);
}

test "read u8 slice" {
    const res = try Reader.init(testing.allocator).read([]const u8,
        io.fixedBufferStream("\x04\x01\x02\x03\x04").inStream());
    const res = try Reader.init(testing.allocator).read([]const u8, io.fixedBufferStream("\x04\x01\x02\x03\x04").inStream());
    defer testing.allocator.free(res);
    const expected = [_]u8{ 1, 2, 3, 4 };
    expectEqualSlices(u8, expected[0..], res[0..]);
}

test "read 0-length slice" {
    const res = try Reader.init(testing.allocator).read([]const u8,
        io.fixedBufferStream("\x00").inStream());
    const res = try Reader.init(testing.allocator).read([]const u8, io.fixedBufferStream("\x00").inStream());
    defer testing.allocator.free(res);
    const expected = [_]u8{};
    expectEqualSlices(u8, expected[0..], res[0..]);


@@ 212,8 198,7 @@ test "read map[string]u8" {
    var r = Reader.init(testing.allocator);
    defer r.deinit();
    const T = std.HashMap([]const u8, u8, std.hash_map.hashString, std.hash_map.eqlString);
    const map = try r.read(T,
        io.fixedBufferStream("\x02\x04zomg\x04\x03lol\x02").inStream());
    const map = try r.read(T, io.fixedBufferStream("\x02\x04zomg\x04\x03lol\x02").inStream());
    expectEqual((map.get("lol") orelse unreachable).value, 2);
    expectEqual((map.get("zomg") orelse unreachable).value, 4);
}


@@ 224,8 209,7 @@ test "read map[u8]void" {

test "read tagged union" {
    const Foo = union(enum) { a: i64, b: bool, c: u8 };
    const res = try Reader.init(testing.allocator).read(Foo,
        io.fixedBufferStream("\x02\x2a").inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream("\x02\x2a").inStream());
    expectEqual(Foo{ .c = 42 }, res);
}



@@ 281,8 265,7 @@ test "write struct" {
    var buf: [@sizeOf(Foo)]u8 = undefined;
    var fbs = io.fixedBufferStream(&buf);
    const expected = "\x00\x00\x28\x42\x2a\x01";
    try Writer.init().write(Foo{ .a = 42.0, .b = 42, .c = true },
        fbs.outStream());
    try Writer.init().write(Foo{ .a = 42.0, .b = 42, .c = true }, fbs.outStream());
    expect(mem.eql(u8, fbs.getWritten(), expected));
}



@@ 432,8 415,7 @@ test "round trip variable uint" {
    var buf: [4]u8 = undefined;
    var fbs = io.fixedBufferStream(&buf);
    try Writer.init().writeVarUint(0x10000, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .readVarUint(io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).readVarUint(io.fixedBufferStream(fbs.getWritten()).inStream());
    expectEqual(res, 0x10000);
}



@@ 441,8 423,7 @@ test "round trip variable int 1" {
    var buf: [4]u8 = undefined;
    var fbs = io.fixedBufferStream(&buf);
    try Writer.init().writeVarInt(-0x10000, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .readVarInt(io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).readVarInt(io.fixedBufferStream(fbs.getWritten()).inStream());
    expectEqual(res, -0x10000);
}



@@ 450,8 431,7 @@ test "round trip variable int 2" {
    var buf: [4]u8 = undefined;
    var fbs = io.fixedBufferStream(&buf);
    try Writer.init().writeVarInt(0x10000, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .readVarInt(io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).readVarInt(io.fixedBufferStream(fbs.getWritten()).inStream());
    expectEqual(res, 0x10000);
}



@@ 460,8 440,7 @@ test "round trip u8" {
    var fbs = io.fixedBufferStream(&buf);
    const x: u8 = 42;
    try Writer.init().write(x, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .read(u8, io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).read(u8, io.fixedBufferStream(fbs.getWritten()).inStream());
    expectEqual(res, x);
}



@@ 476,8 455,7 @@ test "round trip struct" {
    var buf: [@sizeOf(Foo)]u8 = undefined;
    var fbs = io.fixedBufferStream(&buf);
    try Writer.init().write(foo, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .read(Foo, io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream(fbs.getWritten()).inStream());
    expectEqual(res, foo);
}



@@ 491,8 469,7 @@ test "round trip enum" {
    var buf: [@sizeOf(Foo)]u8 = undefined;
    var fbs = io.fixedBufferStream(&buf);
    try Writer.init().write(Foo.c, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .read(Foo, io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream(fbs.getWritten()).inStream());
    expectEqual(res, Foo.c);
}



@@ 501,8 478,7 @@ test "round trip i64 array" {
    var fbs = io.fixedBufferStream(&buf);
    const arr = [_]i64{ -1, 1, math.maxInt(i64), math.minInt(i64) };
    try Writer.init().write(arr, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .read(@TypeOf(arr), io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).read(@TypeOf(arr), io.fixedBufferStream(fbs.getWritten()).inStream());
    expectEqualSlices(i64, arr[0..], res[0..]);
}



@@ 513,8 489,7 @@ test "round trip i32 slice" {
    const expected = [4]i32{ -1, 2, math.maxInt(i32), math.minInt(i32) };
    const slajs: []const i32 = expected[0..];
    try Writer.init().write(slajs, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .read([]const i32, io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).read([]const i32, io.fixedBufferStream(fbs.getWritten()).inStream());
    defer testing.allocator.free(res);
    expectEqualSlices(i32, slajs, res[0..]);
}


@@ 530,8 505,7 @@ test "round trip tagged union" {
    var fbs = io.fixedBufferStream(&buf);

    try Writer.init().write(foo, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .read(Foo, io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream(fbs.getWritten()).inStream());

    expectEqual(foo, res);
}


@@ 547,8 521,7 @@ test "round trip tagged union with void member active" {
    var fbs = io.fixedBufferStream(&buf);

    try Writer.init().write(foo, fbs.outStream());
    const res = try Reader.init(testing.allocator)
        .read(Foo, io.fixedBufferStream(fbs.getWritten()).inStream());
    const res = try Reader.init(testing.allocator).read(Foo, io.fixedBufferStream(fbs.getWritten()).inStream());

    expectEqual(foo, res);
}