From 759d095548e7135bbfeb68ac6b0a21857af49527 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sat, 23 Dec 2023 18:52:53 +0100 Subject: [PATCH] encoding/cbor: ignore struct fields with `cbor:"-"` --- core/encoding/cbor/marshal.odin | 37 ++++++++++++++------ core/encoding/cbor/unmarshal.odin | 4 +++ tests/core/encoding/cbor/test_core_cbor.odin | 3 ++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/core/encoding/cbor/marshal.odin b/core/encoding/cbor/marshal.odin index 898371adf..deb7ba020 100644 --- a/core/encoding/cbor/marshal.odin +++ b/core/encoding/cbor/marshal.odin @@ -422,7 +422,13 @@ marshal_into_encoder :: proc(e: Encoder, v: any) -> (err: Marshal_Error) { case Tag: return err_conv(_encode_tag(e, vv)) } - err_conv(_encode_u16(e, u16(len(info.names)), .Map)) or_return + field_name :: #force_inline proc(info: runtime.Type_Info_Struct, i: int) -> string { + if cbor_name := string(reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "cbor")); cbor_name != "" { + return cbor_name + } else { + return info.names[i] + } + } marshal_entry :: #force_inline proc(e: Encoder, info: runtime.Type_Info_Struct, v: any, name: string, i: int) -> Marshal_Error { err_conv(_encode_text(e, name)) or_return @@ -448,13 +454,14 @@ marshal_into_encoder :: proc(e: Encoder, v: any) -> (err: Marshal_Error) { return marshal_into(e, field_any) } - - field_name :: #force_inline proc(info: runtime.Type_Info_Struct, i: int) -> string { - if cbor_name := string(reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "cbor")); cbor_name != "" { - return cbor_name - } else { - return info.names[i] + + n: u64; { + for _, i in info.names { + if field_name(info, i) != "-" { + n += 1 + } } + err_conv(_encode_u64(e, n, .Map)) or_return } if .Deterministic_Map_Sorting in e.flags { @@ -462,11 +469,16 @@ marshal_into_encoder :: proc(e: Encoder, v: any) -> (err: Marshal_Error) { name: string, field: int, } - entries := make([dynamic]Name, 0, len(info.names), context.temp_allocator) or_return + entries := make([dynamic]Name, 0, n, context.temp_allocator) or_return defer delete(entries) for name, i in info.names { - append(&entries, Name{field_name(info, i), i}) or_return + fname := field_name(info, i) + if fname == "-" { + continue + } + + append(&entries, Name{fname, i}) or_return } // Sort lexicographic on the bytes of the key. @@ -479,7 +491,12 @@ marshal_into_encoder :: proc(e: Encoder, v: any) -> (err: Marshal_Error) { } } else { for name, i in info.names { - marshal_entry(e, info, v, field_name(info, i), i) or_return + fname := field_name(info, i) + if fname == "-" { + continue + } + + marshal_entry(e, info, v, fname, i) or_return } } return diff --git a/core/encoding/cbor/unmarshal.odin b/core/encoding/cbor/unmarshal.odin index ae7f97c98..9ad25a38d 100644 --- a/core/encoding/cbor/unmarshal.odin +++ b/core/encoding/cbor/unmarshal.odin @@ -650,6 +650,10 @@ _unmarshal_map :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header, { for field, field_idx in fields { tag_value := string(reflect.struct_tag_get(field.tag, "cbor")) + if tag_value == "-" { + continue + } + if key == tag_value { use_field_idx = field_idx break diff --git a/tests/core/encoding/cbor/test_core_cbor.odin b/tests/core/encoding/cbor/test_core_cbor.odin index 0fb8b521f..daf31c277 100644 --- a/tests/core/encoding/cbor/test_core_cbor.odin +++ b/tests/core/encoding/cbor/test_core_cbor.odin @@ -130,6 +130,7 @@ Foo :: struct { small_onetwenty: i128, biggest: big.Int, smallest: big.Int, + ignore_this: ^Foo `cbor:"-"`, } FooBar :: enum { @@ -189,6 +190,7 @@ test_marshalling :: proc(t: ^testing.T) { smallie = cbor.Negative_U64(max(u64)), onetwenty = i128(12345), small_onetwenty = -i128(max(u64)), + ignore_this = &Foo{}, } big.atoi(&f.biggest, "1234567891011121314151617181920") @@ -343,6 +345,7 @@ test_marshalling :: proc(t: ^testing.T) { ev(t, backf.smallie, f.smallie) ev(t, backf.onetwenty, f.onetwenty) ev(t, backf.small_onetwenty, f.small_onetwenty) + ev(t, backf.ignore_this, nil) s_equals, s_err := big.equals(&backf.smallest, &f.smallest) ev(t, s_err, nil)