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

This commit is contained in:
Laytan Laats
2024-03-04 17:26:19 +01:00
parent 7854aa22d9
commit 759d095548
3 changed files with 34 additions and 10 deletions
+27 -10
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)) 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 { 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 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) return marshal_into(e, field_any)
} }
field_name :: #force_inline proc(info: runtime.Type_Info_Struct, i: int) -> string { n: u64; {
if cbor_name := string(reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "cbor")); cbor_name != "" { for _, i in info.names {
return cbor_name if field_name(info, i) != "-" {
} else { n += 1
return info.names[i] }
} }
err_conv(_encode_u64(e, n, .Map)) or_return
} }
if .Deterministic_Map_Sorting in e.flags { if .Deterministic_Map_Sorting in e.flags {
@@ -462,11 +469,16 @@ marshal_into_encoder :: proc(e: Encoder, v: any) -> (err: Marshal_Error) {
name: string, name: string,
field: int, 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) defer delete(entries)
for name, i in info.names { 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. // Sort lexicographic on the bytes of the key.
@@ -479,7 +491,12 @@ marshal_into_encoder :: proc(e: Encoder, v: any) -> (err: Marshal_Error) {
} }
} else { } else {
for name, i in info.names { 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 return
+4
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 { for field, field_idx in fields {
tag_value := string(reflect.struct_tag_get(field.tag, "cbor")) tag_value := string(reflect.struct_tag_get(field.tag, "cbor"))
if tag_value == "-" {
continue
}
if key == tag_value { if key == tag_value {
use_field_idx = field_idx use_field_idx = field_idx
break break
@@ -130,6 +130,7 @@ Foo :: struct {
small_onetwenty: i128, small_onetwenty: i128,
biggest: big.Int, biggest: big.Int,
smallest: big.Int, smallest: big.Int,
ignore_this: ^Foo `cbor:"-"`,
} }
FooBar :: enum { FooBar :: enum {
@@ -189,6 +190,7 @@ test_marshalling :: proc(t: ^testing.T) {
smallie = cbor.Negative_U64(max(u64)), smallie = cbor.Negative_U64(max(u64)),
onetwenty = i128(12345), onetwenty = i128(12345),
small_onetwenty = -i128(max(u64)), small_onetwenty = -i128(max(u64)),
ignore_this = &Foo{},
} }
big.atoi(&f.biggest, "1234567891011121314151617181920") big.atoi(&f.biggest, "1234567891011121314151617181920")
@@ -343,6 +345,7 @@ test_marshalling :: proc(t: ^testing.T) {
ev(t, backf.smallie, f.smallie) ev(t, backf.smallie, f.smallie)
ev(t, backf.onetwenty, f.onetwenty) ev(t, backf.onetwenty, f.onetwenty)
ev(t, backf.small_onetwenty, f.small_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) s_equals, s_err := big.equals(&backf.smallest, &f.smallest)
ev(t, s_err, nil) ev(t, s_err, nil)