Skip to content

Commit 98e4dbb

Browse files
committed
v0.6.0
1 parent 651022b commit 98e4dbb

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ A simple API:
1414
```zig
1515
lizpack.encode(...)
1616
lizpack.encodeBounded(...)
17+
lizpack.encodeAlloc(...)
1718
lizpack.decode(...)
1819
lizpack.decodeAlloc(...)
1920
```

build.zig.zon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.{
22
.name = "lizpack",
3-
.version = "0.5.1",
3+
.version = "0.6.0",
44
.minimum_zig_version = "0.14.0-dev.2802+257054a14",
55
.paths = .{
66
"build.zig",

examples/examples.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,12 @@ test "maps" {
237237
const encoded = try lizpack.encode(roles, &out, .{ .format = format });
238238
try std.testing.expectEqualSlices(u8, expected_bytes, encoded);
239239
}
240+
241+
test "encodeAlloc" {
242+
const expected: struct { foo: u8, bar: ?u16 } = .{ .foo = 12, .bar = null };
243+
const slice = try lizpack.encodeAlloc(std.testing.allocator, expected, .{});
244+
defer std.testing.allocator.free(slice);
245+
// the point here is that we don't actually need to know the length of the encoded, we allocate as much as is needed
246+
try std.testing.expectEqual(@as(usize, 12), slice.len);
247+
try std.testing.expectEqual(expected, lizpack.decode(@TypeOf(expected), slice, .{}));
248+
}

src/root.zig

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub fn EncodeOptions(comptime T: type) type {
2424
}
2525

2626
/// Encode the value to MessagePack bytes with format customizations.
27+
/// Writes to the `out` parameter.
2728
pub fn encode(value: anytype, out: []u8, options: EncodeOptions(@TypeOf(value))) EncodeError(@TypeOf(value))![]u8 {
2829
var fbs = std.io.fixedBufferStream(out);
2930
try encodeAny(value, fbs.writer(), options.format);
@@ -44,6 +45,33 @@ pub fn encodeBounded(value: anytype, comptime options: EncodeOptions(@TypeOf(val
4445
return res;
4546
}
4647

48+
pub fn EncodeAllocError(comptime T: type) type {
49+
if (containsSlice(T)) {
50+
return error{
51+
OutOfMemory,
52+
/// MessagePack only supports up to 32 bit lengths of arrays.
53+
/// If usize is 32 bits or smaller, this is unreachable.
54+
SliceLenTooLarge,
55+
};
56+
} else {
57+
return error{OutOfMemory};
58+
}
59+
}
60+
61+
/// Encode the value to MessagePack bytes. Allocates enough bytes as needed.
62+
/// Caller owns the returned slice of encoded bytes (caller is responsible for freeing the returned memory).
63+
pub fn encodeAlloc(allocator: std.mem.Allocator, value: anytype, options: EncodeOptions(@TypeOf(value))) EncodeAllocError(@TypeOf(value))![]u8 {
64+
var bytes = std.ArrayList(u8).init(allocator);
65+
defer bytes.deinit();
66+
try encodeAny(value, bytes.writer(), options.format);
67+
const slice = try bytes.toOwnedSlice();
68+
errdefer unreachable;
69+
if (comptime !containsSlice(@TypeOf(value))) {
70+
assert(largestEncodedSize(@TypeOf(value), options.format) >= slice.len);
71+
}
72+
return slice;
73+
}
74+
4775
pub fn DecodeOptions(comptime T: type) type {
4876
return struct {
4977
format: FormatOptions(T) = FormatOptionsDefault(T),
@@ -209,6 +237,21 @@ pub fn largestEncodedSize(comptime T: type, format_options: FormatOptions(T)) us
209237
};
210238
}
211239

240+
test "encode alloc" {
241+
const expected: struct { foo: u8, bar: ?u16 } = .{ .foo = 12, .bar = null };
242+
const slice = try encodeAlloc(std.testing.allocator, expected, .{});
243+
defer std.testing.allocator.free(slice);
244+
try std.testing.expectEqual(expected, decode(@TypeOf(expected), slice, .{}));
245+
}
246+
247+
test "encodeAlloc failing allocator" {
248+
const expected: struct { foo: u8, bar: ?u16 } = .{ .foo = 12, .bar = null };
249+
try std.testing.expectError(
250+
error.OutOfMemory,
251+
encodeAlloc(std.testing.failing_allocator, expected, .{}),
252+
);
253+
}
254+
212255
test "encode bounded" {
213256
const expected: struct { foo: u8, bar: ?u16 } = .{ .foo = 12, .bar = null };
214257
const slice = encodeBounded(expected, .{}).slice();

0 commit comments

Comments
 (0)