encoding/cbor: ignore struct fields with cbor:"-"

This commit is contained in:
Laytan Laats
2023-12-23 18:52:53 +01:00
parent 7854aa22d9
commit 759d095548
3 changed files with 34 additions and 10 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)