@@ -390,6 +390,9 @@ unmarshal_expect_token :: proc(p: ^Parser, kind: Token_Kind, loc := #caller_loca
390
390
return prev
391
391
}
392
392
393
+ // Struct tags can include not only the name of the JSON key, but also a tag such as `omitempty`.
394
+ // Example: `json:"key_name,omitempty"`
395
+ // This returns the first field as `json_name`, and the rest are returned as `extra`.
393
396
@(private)
394
397
json_name_from_tag_value :: proc (value: string ) -> (json_name, extra: string ) {
395
398
json_name = value
@@ -425,12 +428,6 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
425
428
defer delete (key, p.allocator)
426
429
427
430
unmarshal_expect_token (p, .Colon)
428
-
429
- field_test :: #force_inline proc " contextless" (field_used: [^]byte , offset: uintptr ) -> bool {
430
- prev_set := field_used[offset/8 ] & byte (offset&7 ) != 0
431
- field_used[offset/8 ] |= byte (offset&7 )
432
- return prev_set
433
- }
434
431
435
432
field_used_bytes := (reflect.size_of_typeid (ti.id)+7 )/8
436
433
field_used := intrinsics.alloca (field_used_bytes + 1 , 1 ) // + 1 to not overflow on size_of 0 types.
@@ -449,7 +446,9 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
449
446
450
447
if use_field_idx < 0 {
451
448
for field, field_idx in fields {
452
- if key == field.name {
449
+ tag_value := reflect.struct_tag_get (field.tag, " json" )
450
+ json_name, _ := json_name_from_tag_value (tag_value)
451
+ if json_name == " " && key == field.name {
453
452
use_field_idx = field_idx
454
453
break
455
454
}
@@ -470,7 +469,9 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
470
469
}
471
470
}
472
471
473
- if field.name == key || (field.tag != " " && reflect.struct_tag_get (field.tag, " json" ) == key) {
472
+ tag_value := reflect.struct_tag_get (field.tag, " json" )
473
+ json_name, _ := json_name_from_tag_value (tag_value)
474
+ if (json_name == " " && field.name == key) || json_name == key {
474
475
offset = field.offset
475
476
type = field.type
476
477
found = true
@@ -492,6 +493,11 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
492
493
}
493
494
494
495
if field_found {
496
+ field_test :: #force_inline proc " contextless" (field_used: [^]byte , offset: uintptr ) -> bool {
497
+ prev_set := field_used[offset/8 ] & byte (offset&7 ) != 0
498
+ field_used[offset/8 ] |= byte (offset&7 )
499
+ return prev_set
500
+ }
495
501
if field_test (field_used, offset) {
496
502
return .Multiple_Use_Field
497
503
}
0 commit comments