mirror of
https://github.com/vlang/v.git
synced 2025-09-13 09:25:45 -04:00
x.json2: add skippable field attr @[json: '-']
(improve backwards compatibility with the json
module) (#20892)
This commit is contained in:
parent
71bd94aa9e
commit
c6048d50bf
@ -142,14 +142,20 @@ fn decode_struct[T](_ T, res map[string]Any) !T {
|
|||||||
mut typ := T{}
|
mut typ := T{}
|
||||||
$if T is $struct {
|
$if T is $struct {
|
||||||
$for field in T.fields {
|
$for field in T.fields {
|
||||||
|
mut skip_field := false
|
||||||
mut json_name := field.name
|
mut json_name := field.name
|
||||||
|
|
||||||
for attr in field.attrs {
|
for attr in field.attrs {
|
||||||
if attr.contains('json: ') {
|
if attr.contains('json: ') {
|
||||||
json_name = attr.replace('json: ', '')
|
json_name = attr.replace('json: ', '')
|
||||||
|
if json_name == '-' {
|
||||||
|
skip_field = true
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !skip_field {
|
||||||
$if field.is_enum {
|
$if field.is_enum {
|
||||||
if v := res[json_name] {
|
if v := res[json_name] {
|
||||||
typ.$(field.name) = v.int()
|
typ.$(field.name) = v.int()
|
||||||
@ -251,6 +257,7 @@ fn decode_struct[T](_ T, res map[string]Any) !T {
|
|||||||
return error("The type of `${field.name}` can't be decoded. Please open an issue at https://github.com/vlang/v/issues/new/choose")
|
return error("The type of `${field.name}` can't be decoded. Please open an issue at https://github.com/vlang/v/issues/new/choose")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} $else $if T is $map {
|
} $else $if T is $map {
|
||||||
for k, v in res {
|
for k, v in res {
|
||||||
// // TODO - make this work to decode types like `map[string]StructType[bool]`
|
// // TODO - make this work to decode types like `map[string]StructType[bool]`
|
||||||
|
@ -187,19 +187,29 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut buf []u8) ! {
|
|||||||
}
|
}
|
||||||
$for field in U.fields {
|
$for field in U.fields {
|
||||||
mut ignore_field := false
|
mut ignore_field := false
|
||||||
|
mut skip_field := false
|
||||||
|
|
||||||
value := val.$(field.name)
|
value := val.$(field.name)
|
||||||
|
|
||||||
is_nil := val.$(field.name).str() == '&nil'
|
is_nil := val.$(field.name).str() == '&nil'
|
||||||
|
|
||||||
mut json_name := ''
|
mut json_name := ''
|
||||||
|
|
||||||
for attr in field.attrs {
|
for attr in field.attrs {
|
||||||
if attr.contains('json: ') {
|
if attr.contains('json: ') {
|
||||||
json_name = attr.replace('json: ', '')
|
json_name = attr.replace('json: ', '')
|
||||||
|
if json_name == '-' {
|
||||||
|
ignore_field = true
|
||||||
|
skip_field = true
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if skip_field {
|
||||||
|
i++
|
||||||
|
fields_len--
|
||||||
|
} else {
|
||||||
$if value is $option {
|
$if value is $option {
|
||||||
workaround := val.$(field.name)
|
workaround := val.$(field.name)
|
||||||
if workaround != none { // smartcast
|
if workaround != none { // smartcast
|
||||||
@ -237,7 +247,8 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut buf []u8) ! {
|
|||||||
$if field.indirections != 0 {
|
$if field.indirections != 0 {
|
||||||
if val.$(field.name) != unsafe { nil } {
|
if val.$(field.name) != unsafe { nil } {
|
||||||
$if field.indirections == 1 {
|
$if field.indirections == 1 {
|
||||||
e.encode_value_with_level(*val.$(field.name), level + 1, mut buf)!
|
e.encode_value_with_level(*val.$(field.name), level + 1, mut
|
||||||
|
buf)!
|
||||||
}
|
}
|
||||||
$if field.indirections == 2 {
|
$if field.indirections == 2 {
|
||||||
e.encode_value_with_level(**val.$(field.name), level + 1, mut
|
e.encode_value_with_level(**val.$(field.name), level + 1, mut
|
||||||
@ -318,6 +329,7 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut buf []u8) ! {
|
|||||||
return error('type ${typeof(val).name} cannot be array encoded')
|
return error('type ${typeof(val).name} cannot be array encoded')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if i < fields_len - 1 && !ignore_field {
|
if i < fields_len - 1 && !ignore_field {
|
||||||
if !is_nil {
|
if !is_nil {
|
||||||
|
@ -45,6 +45,35 @@ mut:
|
|||||||
val &T
|
val &T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructTypeSkippedFields[T] {
|
||||||
|
mut:
|
||||||
|
val T @[json: '-']
|
||||||
|
val1 T
|
||||||
|
val2 T @[json: '-']
|
||||||
|
val3 T
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructTypeSkippedFields2[T] {
|
||||||
|
mut:
|
||||||
|
val T
|
||||||
|
val1 T @[json: '-']
|
||||||
|
val2 T
|
||||||
|
val3 T @[json: '-']
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructTypeSkippedFields3[T] {
|
||||||
|
mut:
|
||||||
|
val T @[json: '-']
|
||||||
|
val1 T @[json: '-']
|
||||||
|
val2 T @[json: '-']
|
||||||
|
val3 T @[json: '-']
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructTypeSkippedField4 {
|
||||||
|
mut:
|
||||||
|
val map[string]string @[json: '-']
|
||||||
|
}
|
||||||
|
|
||||||
fn test_types() {
|
fn test_types() {
|
||||||
assert json.decode[StructType[string]]('{"val": ""}')!.val == ''
|
assert json.decode[StructType[string]]('{"val": ""}')!.val == ''
|
||||||
assert json.decode[StructType[string]]('{"val": "0"}')!.val == '0'
|
assert json.decode[StructType[string]]('{"val": "0"}')!.val == '0'
|
||||||
@ -126,3 +155,38 @@ fn test_types() {
|
|||||||
assert true
|
assert true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_skipped_fields() {
|
||||||
|
if x := json.decode[StructTypeSkippedFields[int]]('{"val":10,"val1":10,"val2":10,"val3":10}') {
|
||||||
|
assert x.val == 0
|
||||||
|
assert x.val1 == 10
|
||||||
|
assert x.val2 == 0
|
||||||
|
assert x.val3 == 10
|
||||||
|
} else {
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
|
||||||
|
if x := json.decode[StructTypeSkippedFields2[int]]('{"val":10,"val1":10,"val2":10,"val3":10}') {
|
||||||
|
assert x.val == 10
|
||||||
|
assert x.val1 == 0
|
||||||
|
assert x.val2 == 10
|
||||||
|
assert x.val3 == 0
|
||||||
|
} else {
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
|
||||||
|
if x := json.decode[StructTypeSkippedFields3[int]]('{"val":10,"val1":10,"val2":10,"val3":10}') {
|
||||||
|
assert x.val == 0
|
||||||
|
assert x.val1 == 0
|
||||||
|
assert x.val2 == 0
|
||||||
|
assert x.val3 == 0
|
||||||
|
} else {
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
|
||||||
|
if x := json.decode[StructTypeSkippedField4]('{"val":{"a":"b"}}') {
|
||||||
|
assert x.val.len == 0
|
||||||
|
} else {
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -44,6 +44,30 @@ mut:
|
|||||||
val &T
|
val &T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructTypeSkippedFields[T] {
|
||||||
|
mut:
|
||||||
|
val T @[json: '-']
|
||||||
|
val1 T
|
||||||
|
val2 T @[json: '-']
|
||||||
|
val3 T
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructTypeSkippedFields2[T] {
|
||||||
|
mut:
|
||||||
|
val T
|
||||||
|
val1 T @[json: '-']
|
||||||
|
val2 T
|
||||||
|
val3 T @[json: '-']
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructTypeSkippedFields3[T] {
|
||||||
|
mut:
|
||||||
|
val T @[json: '-']
|
||||||
|
val1 T @[json: '-']
|
||||||
|
val2 T @[json: '-']
|
||||||
|
val3 T @[json: '-']
|
||||||
|
}
|
||||||
|
|
||||||
fn test_types() {
|
fn test_types() {
|
||||||
assert json.encode(StructType[string]{}) == '{"val":""}'
|
assert json.encode(StructType[string]{}) == '{"val":""}'
|
||||||
assert json.encode(StructType[string]{ val: '' }) == '{"val":""}'
|
assert json.encode(StructType[string]{ val: '' }) == '{"val":""}'
|
||||||
@ -211,6 +235,29 @@ fn test_option_array() {
|
|||||||
// }) == '{"val":[[0,1],[0,2,3],[2],[5,1]]}'
|
// }) == '{"val":[[0,1],[0,2,3],[2],[5,1]]}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_skipped_fields() {
|
||||||
|
assert json.encode(StructTypeSkippedFields[string]{
|
||||||
|
val: ''
|
||||||
|
val1: ''
|
||||||
|
val2: ''
|
||||||
|
val3: ''
|
||||||
|
}) == '{"val1":"","val3":""}'
|
||||||
|
|
||||||
|
assert json.encode(StructTypeSkippedFields2[string]{
|
||||||
|
val: ''
|
||||||
|
val1: ''
|
||||||
|
val2: ''
|
||||||
|
val3: ''
|
||||||
|
}) == '{"val":"","val2":""}'
|
||||||
|
|
||||||
|
assert json.encode(StructTypeSkippedFields3[string]{
|
||||||
|
val: ''
|
||||||
|
val1: ''
|
||||||
|
val2: ''
|
||||||
|
val3: ''
|
||||||
|
}) == '{}'
|
||||||
|
}
|
||||||
|
|
||||||
fn test_alias() {
|
fn test_alias() {
|
||||||
assert json.encode(StructType[StringAlias]{}) == '{"val":""}'
|
assert json.encode(StructType[StringAlias]{}) == '{"val":""}'
|
||||||
assert json.encode(StructType[StringAlias]{ val: '' }) == '{"val":""}'
|
assert json.encode(StructType[StringAlias]{ val: '' }) == '{"val":""}'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user