Compare commits
No commits in common. "master" and "v1.0.0" have entirely different histories.
4 changed files with 182 additions and 842 deletions
|
@ -1,4 +1,2 @@
|
|||
# Zig CBOR
|
||||
A Fast & flexible cbor encoding, decoding and matching library for Zig
|
||||
|
||||
[](https://deepwiki.com/neurocyte/cbor)
|
||||
|
|
|
@ -9,11 +9,9 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("test/tests.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
.root_source_file = b.path("test/tests.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
tests.root_module.addImport("cbor", cbor_mod);
|
||||
|
||||
|
|
721
src/cbor.zig
721
src/cbor.zig
File diff suppressed because it is too large
Load diff
293
test/tests.zig
293
test/tests.zig
|
@ -1,11 +1,9 @@
|
|||
const std = @import("std");
|
||||
const cbor_mod = @import("cbor");
|
||||
|
||||
const Io = std.Io;
|
||||
const expect = std.testing.expect;
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
const expectEqualDeep = std.testing.expectEqualDeep;
|
||||
const expectEqualStrings = std.testing.expectEqualStrings;
|
||||
const expectError = std.testing.expectError;
|
||||
|
||||
const fmt = cbor_mod.fmt;
|
||||
|
@ -25,7 +23,6 @@ const writeArrayHeader = cbor_mod.writeArrayHeader;
|
|||
const writeMapHeader = cbor_mod.writeMapHeader;
|
||||
const writeValue = cbor_mod.writeValue;
|
||||
const extract = cbor_mod.extract;
|
||||
const extractAlloc = cbor_mod.extractAlloc;
|
||||
const extract_cbor = cbor_mod.extract_cbor;
|
||||
|
||||
const more = cbor_mod.more;
|
||||
|
@ -207,29 +204,31 @@ test "cbor.nulls" {
|
|||
|
||||
test "cbor.stream_writer" {
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeArrayHeader(&writer, 5);
|
||||
try writeValue(&writer, "five");
|
||||
try writeValue(&writer, 5);
|
||||
try writeValue(&writer, "four");
|
||||
try writeValue(&writer, 4);
|
||||
try writeArrayHeader(&writer, 2);
|
||||
try writeValue(&writer, "three");
|
||||
try writeValue(&writer, 3);
|
||||
try expect(try match(writer.buffered(), .{ "five", 5, "four", 4, .{ "three", 3 } }));
|
||||
var stream = std.io.fixedBufferStream(&buf);
|
||||
const writer = stream.writer();
|
||||
try writeArrayHeader(writer, 5);
|
||||
try writeValue(writer, "five");
|
||||
try writeValue(writer, 5);
|
||||
try writeValue(writer, "four");
|
||||
try writeValue(writer, 4);
|
||||
try writeArrayHeader(writer, 2);
|
||||
try writeValue(writer, "three");
|
||||
try writeValue(writer, 3);
|
||||
try expect(try match(stream.getWritten(), .{ "five", 5, "four", 4, .{ "three", 3 } }));
|
||||
}
|
||||
|
||||
test "cbor.stream_object_writer" {
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeMapHeader(&writer, 3);
|
||||
try writeValue(&writer, "five");
|
||||
try writeValue(&writer, 5);
|
||||
try writeValue(&writer, "four");
|
||||
try writeValue(&writer, 4);
|
||||
try writeValue(&writer, "three");
|
||||
try writeValue(&writer, 3);
|
||||
const obj = writer.buffered();
|
||||
var stream = std.io.fixedBufferStream(&buf);
|
||||
const writer = stream.writer();
|
||||
try writeMapHeader(writer, 3);
|
||||
try writeValue(writer, "five");
|
||||
try writeValue(writer, 5);
|
||||
try writeValue(writer, "four");
|
||||
try writeValue(writer, 4);
|
||||
try writeValue(writer, "three");
|
||||
try writeValue(writer, 3);
|
||||
const obj = stream.getWritten();
|
||||
var json_buf: [128]u8 = undefined;
|
||||
const json = try toJson(obj, &json_buf);
|
||||
try expectEqualDeep(json,
|
||||
|
@ -520,253 +519,5 @@ test "cbor.extract_cbor f64" {
|
|||
const json2 = try toJsonAlloc(std.testing.allocator, sub);
|
||||
defer std.testing.allocator.free(json2);
|
||||
|
||||
try expectEqualStrings("[0.9689138531684875]", json2);
|
||||
}
|
||||
|
||||
test "cbor.writeValue enum" {
|
||||
const TestEnum = enum { a, b };
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeValue(&writer, TestEnum.a);
|
||||
const expected = @tagName(TestEnum.a);
|
||||
var m = std.json.Value{ .null = {} };
|
||||
try expect(try match(writer.buffered(), extract(&m)));
|
||||
try expectEqualStrings(expected, m.string);
|
||||
}
|
||||
|
||||
test "cbor.extract enum" {
|
||||
const TestEnum = enum { a, b };
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeValue(&writer, TestEnum.a);
|
||||
var m: TestEnum = undefined;
|
||||
try expect(try match(writer.buffered(), extract(&m)));
|
||||
try expectEqualStrings(@tagName(m), @tagName(TestEnum.a));
|
||||
try expect(m == .a);
|
||||
}
|
||||
|
||||
test "cbor.writeValue tagged union" {
|
||||
const TestUnion = union(enum) { a: f32, b: []const u8 };
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeValue(&writer, TestUnion{ .b = "should work" });
|
||||
var tagName = std.json.Value{ .null = {} };
|
||||
var value = std.json.Value{ .null = {} };
|
||||
var iter: []const u8 = writer.buffered();
|
||||
try expect(try matchValue(&iter, .{ extract(&tagName), extract(&value) }));
|
||||
try expectEqualStrings(@tagName(TestUnion.b), tagName.string);
|
||||
try expectEqualStrings("should work", value.string);
|
||||
}
|
||||
|
||||
test "cbor.writeValue tagged union no payload types" {
|
||||
const TestUnion = union(enum) { a, b };
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeValue(&writer, TestUnion.b);
|
||||
|
||||
try expect(try match(writer.buffered(), @tagName(TestUnion.b)));
|
||||
var tagName = std.json.Value{ .null = {} };
|
||||
try expect(try match(writer.buffered(), extract(&tagName)));
|
||||
try expectEqualStrings(@tagName(TestUnion.b), tagName.string);
|
||||
}
|
||||
|
||||
test "cbor.writeValue nested union json" {
|
||||
const TestUnion = union(enum) {
|
||||
a: f32,
|
||||
b: []const u8,
|
||||
c: []const union(enum) {
|
||||
d: f32,
|
||||
e: i32,
|
||||
f,
|
||||
},
|
||||
};
|
||||
var buf: [256]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena.deinit();
|
||||
try writeValue(&writer, TestUnion{ .c = &.{ .{ .d = 1.5 }, .{ .e = 5 }, .f } });
|
||||
var json_buf: [128]u8 = undefined;
|
||||
const json = try toJson(writer.buffered(), &json_buf);
|
||||
try expectEqualStrings(json,
|
||||
\\["c",[["d",1.5],["e",5],["f"]]]
|
||||
);
|
||||
}
|
||||
|
||||
test "cbor.extract tagged union" {
|
||||
const TestUnion = union(enum) { a: f32, b: []const u8 };
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeValue(&writer, TestUnion{ .b = "should work" });
|
||||
var m: TestUnion = undefined;
|
||||
try expect(try match(writer.buffered(), extract(&m)));
|
||||
try expectEqualDeep(TestUnion{ .b = "should work" }, m);
|
||||
}
|
||||
|
||||
test "cbor.extract nested union" {
|
||||
const TestUnion = union(enum) {
|
||||
a: f32,
|
||||
b: []const u8,
|
||||
c: []const union(enum) {
|
||||
d: f32,
|
||||
e: i32,
|
||||
f,
|
||||
},
|
||||
};
|
||||
var buf: [256]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
const allocator = arena.allocator();
|
||||
defer arena.deinit();
|
||||
try writeValue(&writer, TestUnion{ .c = &.{ .{ .d = 1.5 }, .{ .e = 5 }, .f } });
|
||||
var m: TestUnion = undefined;
|
||||
try expect(try match(writer.buffered(), extractAlloc(&m, allocator)));
|
||||
try expectEqualDeep(TestUnion{ .c = &.{ .{ .d = 1.5 }, .{ .e = 5 }, .f } }, m);
|
||||
}
|
||||
|
||||
test "cbor.extract struct no fields" {
|
||||
const TestStruct = struct {};
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeValue(&writer, TestStruct{});
|
||||
var m: TestStruct = undefined;
|
||||
try expect(try match(writer.buffered(), extract(&m)));
|
||||
try expectEqualDeep(TestStruct{}, m);
|
||||
}
|
||||
|
||||
test "cbor.extract_cbor struct" {
|
||||
const TestStruct = struct {
|
||||
a: f32,
|
||||
b: []const u8,
|
||||
};
|
||||
var buf: [128]u8 = undefined;
|
||||
const v = TestStruct{ .a = 1.5, .b = "hello" };
|
||||
const m = fmt(&buf, v);
|
||||
var map_cbor: []const u8 = undefined;
|
||||
try expect(try match(m, extract_cbor(&map_cbor)));
|
||||
var json_buf: [256]u8 = undefined;
|
||||
const json = try toJson(map_cbor, &json_buf);
|
||||
try expectEqualStrings(json,
|
||||
\\{"a":1.5,"b":"hello"}
|
||||
);
|
||||
}
|
||||
|
||||
test "cbor.extract struct" {
|
||||
const TestStruct = struct {
|
||||
a: f32,
|
||||
b: []const u8,
|
||||
};
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
const v = TestStruct{ .a = 1.5, .b = "hello" };
|
||||
try writeValue(&writer, v);
|
||||
var obj: TestStruct = undefined;
|
||||
var json_buf: [256]u8 = undefined;
|
||||
var iter: []const u8 = writer.buffered();
|
||||
const t = try decodeType(&iter);
|
||||
try expectEqual(5, t.major);
|
||||
const json = try toJson(writer.buffered(), &json_buf);
|
||||
try expectEqualStrings(json,
|
||||
\\{"a":1.5,"b":"hello"}
|
||||
);
|
||||
try expect(try match(writer.buffered(), extract(&obj)));
|
||||
try expectEqual(1.5, obj.a);
|
||||
try expectEqualStrings("hello", obj.b);
|
||||
}
|
||||
|
||||
test "cbor.extractAlloc struct" {
|
||||
const TestStruct = struct {
|
||||
a: f32,
|
||||
b: []const u8,
|
||||
};
|
||||
var buf: [128]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||
const allocator = arena.allocator();
|
||||
defer arena.deinit();
|
||||
const v = TestStruct{ .a = 1.5, .b = "hello" };
|
||||
try writeValue(&writer, v);
|
||||
var obj: TestStruct = undefined;
|
||||
try expect(try match(writer.buffered(), extractAlloc(&obj, allocator)));
|
||||
try expectEqual(1.5, obj.a);
|
||||
try expectEqualStrings("hello", obj.b);
|
||||
}
|
||||
|
||||
fn test_value_write_and_extract(T: type, value: T) !void {
|
||||
const test_value: T = value;
|
||||
var buf: [1024]u8 = undefined;
|
||||
var writer: Io.Writer = .fixed(&buf);
|
||||
try writeValue(&writer, test_value);
|
||||
|
||||
var result_value: T = undefined;
|
||||
|
||||
var iter: []const u8 = writer.buffered();
|
||||
try expect(try matchValue(&iter, extract(&result_value)));
|
||||
|
||||
switch (comptime @typeInfo(T)) {
|
||||
.pointer => |ptr_info| switch (ptr_info.size) {
|
||||
.slice => if (ptr_info.child == u8) return expectEqualStrings(test_value, result_value),
|
||||
else => {},
|
||||
},
|
||||
.optional => |opt_info| switch (comptime @typeInfo(opt_info.child)) {
|
||||
.pointer => |ptr_info| switch (ptr_info.size) {
|
||||
.slice => if (ptr_info.child == u8) {
|
||||
if (test_value == null and result_value == null) return;
|
||||
if (test_value == null or result_value == null) return error.TestExpectedEqual;
|
||||
return expectEqualStrings(test_value.?, result_value.?);
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return expectEqual(test_value, result_value);
|
||||
}
|
||||
|
||||
test "read/write optional bool (null)" {
|
||||
try test_value_write_and_extract(?bool, null);
|
||||
}
|
||||
|
||||
test "read/write optional bool (true)" {
|
||||
try test_value_write_and_extract(?bool, true);
|
||||
}
|
||||
|
||||
test "read/write optional bool (false)" {
|
||||
try test_value_write_and_extract(?bool, false);
|
||||
}
|
||||
|
||||
test "read/write optional string (null)" {
|
||||
try test_value_write_and_extract(?[]const u8, null);
|
||||
}
|
||||
|
||||
test "read/write optional string (non-null)" {
|
||||
try test_value_write_and_extract(?[]const u8, "TESTME");
|
||||
}
|
||||
|
||||
test "read/write optional struct (null)" {
|
||||
try test_value_write_and_extract(?struct { field: usize }, null);
|
||||
}
|
||||
|
||||
test "read/write optional struct (non-null)" {
|
||||
try test_value_write_and_extract(?struct { field: usize }, .{ .field = 42 });
|
||||
}
|
||||
|
||||
test "read/write struct optional field (null)" {
|
||||
try test_value_write_and_extract(struct { field: ?usize }, .{ .field = null });
|
||||
}
|
||||
|
||||
test "read/write struct optional field (non-null)" {
|
||||
try test_value_write_and_extract(struct { field: ?usize }, .{ .field = 42 });
|
||||
}
|
||||
|
||||
test "read/write optional struct optional field (null) (na)" {
|
||||
try test_value_write_and_extract(?struct { field: ?usize }, null);
|
||||
}
|
||||
|
||||
test "read/write optional struct optional field (non-null) (null)" {
|
||||
try test_value_write_and_extract(?struct { field: ?usize }, .{ .field = null });
|
||||
}
|
||||
|
||||
test "read/write optional struct optional field (non-null) (non=null)" {
|
||||
try test_value_write_and_extract(?struct { field: ?usize }, .{ .field = 42 });
|
||||
try expectEqualDeep("[9.689138531684875e-1]", json2);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue