@@ -144,7 +144,7 @@ pub fn packStruct(writer: *std.Io.Writer, comptime T: type, value_or_maybe_null:
144144 if (has_custom_write_fn ) {
145145 return try value .msgpackWrite (packer (writer ));
146146 } else {
147- const format = comptime if (std .meta .hasFn (Type , "msgpackFormat" )) T .msgpackFormat () else default_struct_format ;
147+ const format = comptime if (std .meta .hasFn (Type , "msgpackFormat" )) Type .msgpackFormat () else default_struct_format ;
148148 switch (format ) {
149149 .as_map = > | opts | {
150150 return packStructAsMap (writer , Type , value , opts );
@@ -160,7 +160,7 @@ pub fn unpackStructFromMapBody(reader: *std.Io.Reader, allocator: std.mem.Alloca
160160 const Type = NonOptional (T );
161161 const type_info = @typeInfo (Type );
162162 const fields = type_info .@"struct" .fields ;
163- const FieldEnum = std .meta .FieldEnum (T );
163+ const FieldEnum = std .meta .FieldEnum (Type );
164164
165165 var fields_seen = std .bit_set .StaticBitSet (fields .len ).initEmpty ();
166166
@@ -208,10 +208,10 @@ pub fn unpackStructFromMapBody(reader: *std.Io.Reader, allocator: std.mem.Alloca
208208 }
209209 },
210210 .custom = > {
211- const KeyType = comptime @typeInfo (@TypeOf (T .msgpackFieldKey )).@"fn" .return_type .? ;
211+ const KeyType = comptime @typeInfo (@TypeOf (Type .msgpackFieldKey )).@"fn" .return_type .? ;
212212 const key = try unpackAny (reader , allocator , KeyType );
213213 inline for (fields , 0.. ) | field , i | {
214- if (T .msgpackFieldKey (@field (FieldEnum , field .name )) == key ) {
214+ if (Type .msgpackFieldKey (@field (FieldEnum , field .name )) == key ) {
215215 fields_seen .set (i );
216216 @field (result , field .name ) = try unpackAny (reader , allocator , field .type );
217217 break ;
@@ -280,9 +280,9 @@ pub fn unpackStruct(reader: *std.Io.Reader, allocator: std.mem.Allocator, compti
280280
281281 const has_custom_read_fn = std .meta .hasFn (Type , "msgpackRead" );
282282 if (has_custom_read_fn ) {
283- return try T .msgpackRead (unpacker (reader , allocator ));
283+ return try Type .msgpackRead (unpacker (reader , allocator ));
284284 } else {
285- const format = comptime if (std .meta .hasFn (Type , "msgpackFormat" )) T .msgpackFormat () else default_struct_format ;
285+ const format = comptime if (std .meta .hasFn (Type , "msgpackFormat" )) Type .msgpackFormat () else default_struct_format ;
286286 switch (format ) {
287287 .as_map = > | opts | {
288288 return try unpackStructAsMap (reader , allocator , T , opts );
@@ -318,6 +318,68 @@ test "writeStruct: map_by_index" {
318318 }, writer .buffered ());
319319}
320320
321+ test "writeStruct: optional custom format" {
322+ const Msg = struct {
323+ a : u32 ,
324+
325+ pub fn msgpackFormat () StructFormat {
326+ return .{ .as_map = .{ .key = .field_index } };
327+ }
328+ };
329+
330+ var buffer : [100 ]u8 = undefined ;
331+ var writer = std .Io .Writer .fixed (& buffer );
332+ try packStruct (& writer , ? Msg , Msg { .a = 1 });
333+
334+ try std .testing .expectEqualSlices (u8 , &.{
335+ 0x81 ,
336+ 0x00 ,
337+ 0x01 ,
338+ }, writer .buffered ());
339+ }
340+
341+ test "readStruct: optional custom field key" {
342+ const Msg = struct {
343+ a : u32 ,
344+
345+ pub fn msgpackFormat () StructFormat {
346+ return .{ .as_map = .{ .key = .custom } };
347+ }
348+
349+ pub fn msgpackFieldKey (field : std .meta .FieldEnum (@This ())) u8 {
350+ return switch (field ) {
351+ .a = > 1 ,
352+ };
353+ }
354+ };
355+
356+ const packed_msg = [_ ]u8 {
357+ 0x81 ,
358+ 0x01 ,
359+ 0x2a ,
360+ };
361+ var reader = std .Io .Reader .fixed (& packed_msg );
362+ const decoded = try unpackStruct (& reader , std .testing .allocator , ? Msg );
363+
364+ try std .testing .expectEqual (@as (? Msg , Msg { .a = 42 }), decoded );
365+ }
366+
367+ test "readStruct: optional custom reader" {
368+ const Msg = struct {
369+ a : u32 ,
370+
371+ pub fn msgpackRead (unpacker_value : anytype ) ! @This () {
372+ return .{ .a = try unpacker_value .readInt (u32 ) };
373+ }
374+ };
375+
376+ const packed_msg = [_ ]u8 {0x2a };
377+ var reader = std .Io .Reader .fixed (& packed_msg );
378+ const decoded = try unpackStruct (& reader , std .testing .allocator , ? Msg );
379+
380+ try std .testing .expectEqual (@as (? Msg , Msg { .a = 42 }), decoded );
381+ }
382+
321383test "writeStruct: map by field_name" {
322384 const Msg = struct {
323385 a : u32 ,
0 commit comments