@@ -24,6 +24,7 @@ pub fn EncodeOptions(comptime T: type) type {
24
24
}
25
25
26
26
/// Encode the value to MessagePack bytes with format customizations.
27
+ /// Writes to the `out` parameter.
27
28
pub fn encode (value : anytype , out : []u8 , options : EncodeOptions (@TypeOf (value ))) EncodeError (@TypeOf (value ))! []u8 {
28
29
var fbs = std .io .fixedBufferStream (out );
29
30
try encodeAny (value , fbs .writer (), options .format );
@@ -44,6 +45,33 @@ pub fn encodeBounded(value: anytype, comptime options: EncodeOptions(@TypeOf(val
44
45
return res ;
45
46
}
46
47
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
+
47
75
pub fn DecodeOptions (comptime T : type ) type {
48
76
return struct {
49
77
format : FormatOptions (T ) = FormatOptionsDefault (T ),
@@ -209,6 +237,21 @@ pub fn largestEncodedSize(comptime T: type, format_options: FormatOptions(T)) us
209
237
};
210
238
}
211
239
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
+
212
255
test "encode bounded" {
213
256
const expected : struct { foo : u8 , bar : ? u16 } = .{ .foo = 12 , .bar = null };
214
257
const slice = encodeBounded (expected , .{}).slice ();
0 commit comments