@@ 27,7 27,7 @@ pub const Decoder = struct {
}
/// Decode a supported BARE type.
- pub fn decode(self: *Self, comptime T: type, reader: anytype) !if (isHashMap(T)) T.Unmanaged else T {
+ pub fn decode(self: *Self, comptime T: type, reader: anytype) !ReturnType(T) {
return switch (@typeInfo(T)) {
.Int => self.decodeInt(T, reader),
.Float => self.decodeFloat(T, reader),
@@ 213,6 213,10 @@ pub const Decoder = struct {
return map;
}
+
+ fn ReturnType(comptime T: type) type {
+ return if (isHashMap(T)) T.Unmanaged else T;
+ }
};
/// Encodes a BARE message.
@@ 376,14 380,17 @@ pub const Encoder = struct {
fn isHashMap(comptime T: type) bool {
switch (@typeInfo(T)) {
- .Struct => {},
+ .Struct => {
+ // These are the only parts of the HashMap API that are used.
+ // `HashMapKeyType` and `HashMapValueType` add further constraints.
+ const has1 = @hasDecl(T, "iterator");
+ const has2 = @hasDecl(T, "putAssumeCapacity");
+ const has3 = @hasDecl(T, "ensureCapacity");
+ const has4 = @hasDecl(T, "Size");
+ return has1 and has2 and has3 and has4;
+ },
else => return false,
}
- // These are the only parts of the HashMap API that are used.
- // `HashMapKeyType` and `HashMapValueType` add further constraints.
- const has1 = @hasDecl(T, "iterator") or @hasDecl(T, "items");
- const has2 = @hasDecl(T, "putAssumeCapacity") and @hasDecl(T, "ensureCapacity");
- return has1 and has2 and @hasDecl(T, "Size") and @hasDecl(T, "Unmanaged");
}
fn HashMapKeyType(comptime T: type) type {
@@ 14,7 14,7 @@ const expectEqual = testing.expectEqual;
const expectEqualSlices = testing.expectEqualSlices;
const expectError = testing.expectError;
-test "" {
+test "refAllDecls" {
std.testing.refAllDecls(bare);
}
@@ 143,7 143,7 @@ test "read struct 6" {
test "read struct with void members" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var fbs = io.fixedBufferStream("lol");
\\ const Foo = struct { a: u8, b: void };
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@@ 267,7 267,7 @@ test "read map overflow" {
test "read map[u8]void" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var fbs = io.fixedBufferStream("lol");
\\ const HM = std.AutoHashMap(u8, void);
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@@ 288,7 288,7 @@ test "read tagged union" {
test "read untagged union" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ const Foo = union { a: u8, b: void };
\\ var fbs = io.fixedBufferStream("lol");
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@@ 300,7 300,7 @@ test "read untagged union" {
test "read void" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var fbs = io.fixedBufferStream("lol");
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
\\ var d = Decoder.init(gpa.allocator());
@@ 311,7 311,7 @@ test "read void" {
test "read unsupported integer type" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var fbs = io.fixedBufferStream("lol");
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
\\ var d = Decoder.init(gpa.allocator());
@@ 322,7 322,7 @@ test "read unsupported integer type" {
test "read unsupported float type" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var fbs = io.fixedBufferStream("lol");
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
\\ var d = Decoder.init(gpa.allocator());
@@ 333,7 333,7 @@ test "read unsupported float type" {
test "read unsupported pointer type" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var fbs = io.fixedBufferStream("lol");
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
\\ var d = Decoder.init(gpa.allocator());
@@ 378,7 378,7 @@ test "write struct" {
test "write struct with void members" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ const Foo = struct { x: u8, y: void };
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
@@ 425,7 425,7 @@ test "write optional u8 null" {
test "write optional void" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ const foo: ?void = null;
@@ 448,7 448,7 @@ test "write u8 array" {
test "write array of void" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ const foo: [4]void = .{ {}, {}, {}, {} };
@@ 474,7 474,7 @@ test "write slice" {
test "write slice of void" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ const foo: []const void = &[_]void{ {}, {} };
@@ 521,7 521,7 @@ test "write map[string]u8" {
test "write map[u8]void" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ const foo = std.AutoHashMap(u8, void);
@@ 560,7 560,7 @@ test "write tagged union with void member active" {
test "write untagged union" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ const Foo = union { a: u8, b: void };
\\ var fbs = io.fixedBufferStream("lol");
\\ var e = Encoder.init();
@@ 571,7 571,7 @@ test "write untagged union" {
test "write void" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ var e = Encoder.init();
@@ 582,7 582,7 @@ test "write void" {
test "write unsupported integer type" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ const foo: u7 = 7;
@@ 594,7 594,7 @@ test "write unsupported integer type" {
test "write unsupported float type" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ const foo: f16 = 4.2;
@@ 606,7 606,7 @@ test "write unsupported float type" {
test "write unsupported pointer type" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ const x: u8 = 2;
@@ 755,7 755,7 @@ test "bare.Decoder frees its memory" {
test "invariant: fixed-length array must have length > 0 (read)" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var fbs = io.fixedBufferStream("lol");
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
\\ var d = Decoder.init(gpa.allocator());
@@ 766,7 766,7 @@ test "invariant: fixed-length array must have length > 0 (read)" {
test "invariant: fixed-length array must have length > 0 (write)" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ var foo = [0]u8{};
@@ 778,7 778,7 @@ test "invariant: fixed-length array must have length > 0 (write)" {
test "invariant: structs must have at least 1 field (read)" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ const Foo = struct {};
\\ var fbs = io.fixedBufferStream("lol");
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@@ 790,7 790,7 @@ test "invariant: structs must have at least 1 field (read)" {
test "invariant: structs must have at least 1 field (write)" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ const Foo = struct {};
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
@@ 802,50 802,55 @@ test "invariant: structs must have at least 1 field (write)" {
test "invariant: unions must have at least 1 field (read)" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ const Foo = union(enum) {};
\\ var fbs = io.fixedBufferStream("lol");
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
\\ var d = Decoder.init(gpa.allocator());
- \\ try d.decode(Foo{}, fbs.reader());
+ \\ _ = try d.decode(Foo, fbs.reader());
\\}
, "union declarations must have at least one tag");
}
test "invariant: unions must have at least 1 field (write)" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ const Foo = union(enum) {};
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ var e = Encoder.init();
- \\ try e.encode(Foo{}, fbs.writer());
+ \\ const foo: Foo = .{};
+ \\ _ = try e.encode(foo, fbs.writer());
\\}
, "union declarations must have at least one tag");
}
test "invariant: hashmap keys must be of primitive type" {
try testCompileError(
- \\pub fn main() void {
+ \\pub fn main() !void {
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
\\ const hm = std.AutoHashMap([64]u8, void).init(gpa.allocator());
\\ var buf: [0x100]u8 = undefined;
\\ var fbs = io.fixedBufferStream(&buf);
\\ var e = Encoder.init();
- \\ try e.encode(hm, fbs.writer());
+ \\ _ = try e.encode(hm, fbs.writer());
\\}
, "unsupported hashmap key type [64]u8");
}
test "invariant: enum values must be unique" {
try testCompileError(
- \\pub fn main() void {
- \\ const Foo = enum(u8) {
- \\ x = 1,
- \\ y = 1,
- \\ };
- \\ _ = Foo;
- \\}
+ \\pub fn main() !void {
+ \\ const Foo = enum(u8) {
+ \\ x = 1,
+ \\ y = 1,
+ \\ };
+ \\ var buf: [0x100]u8 = undefined;
+ \\ var fbs = io.fixedBufferStream(&buf);
+ \\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ \\ var d = Decoder.init(gpa.allocator());
+ \\ _ = try d.decode(Foo, fbs.reader());
+ \\}
, "enum tag value 1 already taken");
}
@@ 890,8 895,6 @@ fn checkErrorMessage(haystack: []const u8, message: []const u8) !void {
return;
};
const errorslice = haystack[idx + errorstart.len ..];
- const starts_with = mem.startsWith(u8, errorslice, message);
- if (!starts_with)
- std.log.err("\nunexpected output: `{s}`; expected: `{s}`", .{ errorslice, message });
- try expect(starts_with);
+
+ try testing.expectStringStartsWith(errorslice, message);
}