mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
x.json2: refactor/fix json2.encode, add more tests (#16790)
This commit is contained in:
parent
e3aee748ac
commit
8f217c00e5
@ -56,6 +56,12 @@ fn test_types() {
|
||||
|
||||
assert json.encode(StructType[time.Time]{}) == '{"val":"0000-00-00T00:00:00.000Z"}'
|
||||
assert json.encode(StructType[time.Time]{ val: fixed_time }) == '{"val":"2022-03-11T13:54:25.000Z"}'
|
||||
|
||||
assert json.encode(StructType[StructType[int]]{
|
||||
val: StructType[int]{
|
||||
val: 1
|
||||
}
|
||||
}) == '{"val":{"val":1}}'
|
||||
}
|
||||
|
||||
fn test_optional_types() {
|
||||
@ -75,6 +81,7 @@ fn test_optional_types() {
|
||||
assert json.encode(StructTypeOptional[int]{ val: 1 }) == '{"val":1}'
|
||||
|
||||
assert json.encode(StructTypeOptional[time.Time]{}) == '{}'
|
||||
assert json.encode(StructTypeOptional[time.Time]{ val: time.Time{} }) == '{"val":"0000-00-00T00:00:00.000Z"}'
|
||||
assert json.encode(StructTypeOptional[time.Time]{ val: fixed_time }) == '{"val":"2022-03-11T13:54:25.000Z"}'
|
||||
}
|
||||
|
||||
@ -119,15 +126,63 @@ fn test_array() {
|
||||
assert json.encode(StructType[[]bool]{ val: [true] }) == '{"val":[true]}'
|
||||
assert json.encode(StructType[[]bool]{ val: [false] }) == '{"val":[false]}'
|
||||
assert json.encode(StructType[[]bool]{ val: [false, true, false] }) == '{"val":[false,true,false]}'
|
||||
|
||||
array_of_struct := [StructType[bool]{
|
||||
val: true
|
||||
}, StructType[bool]{
|
||||
val: false
|
||||
}]
|
||||
assert json.encode(StructType[[]StructType[bool]]{ val: array_of_struct }) == '{"val":[{"val":true},{"val":false}]}'
|
||||
}
|
||||
|
||||
fn test_optional_array() {
|
||||
assert json.encode(StructTypeOptional[[]int]{ val: none }) == '{}'
|
||||
assert json.encode(StructTypeOptional[[]string]{}) == '{}'
|
||||
assert json.encode(StructTypeOptional[[]string]{ val: [] }) == '{"val":[]}'
|
||||
assert json.encode(StructTypeOptional[[]string]{ val: ['0'] }) == '{"val":["0"]}'
|
||||
assert json.encode(StructTypeOptional[[]string]{ val: ['1'] }) == '{"val":["1"]}'
|
||||
|
||||
assert json.encode(StructTypeOptional[[]int]{}) == '{}'
|
||||
assert json.encode(StructTypeOptional[[]int]{ val: [] }) == '{"val":[]}'
|
||||
assert json.encode(StructTypeOptional[[]int]{ val: [0] }) == '{"val":[0]}'
|
||||
assert json.encode(StructTypeOptional[[]int]{ val: [1] }) == '{"val":[1]}'
|
||||
assert json.encode(StructTypeOptional[[]int]{ val: [0, 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
|
||||
|
||||
assert json.encode(StructTypeOptional[[]byte]{}) == '{}'
|
||||
assert json.encode(StructTypeOptional[[]byte]{ val: [] }) == '{"val":[]}'
|
||||
assert json.encode(StructTypeOptional[[]byte]{ val: [byte(0)] }) == '{"val":[0]}'
|
||||
assert json.encode(StructTypeOptional[[]byte]{ val: [byte(1)] }) == '{"val":[1]}'
|
||||
assert json.encode(StructTypeOptional[[]byte]{ val: [byte(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
|
||||
|
||||
assert json.encode(StructTypeOptional[[]i64]{}) == '{}'
|
||||
assert json.encode(StructTypeOptional[[]i64]{ val: [] }) == '{"val":[]}'
|
||||
assert json.encode(StructTypeOptional[[]i64]{ val: [i64(0)] }) == '{"val":[0]}'
|
||||
assert json.encode(StructTypeOptional[[]i64]{ val: [i64(1)] }) == '{"val":[1]}'
|
||||
assert json.encode(StructTypeOptional[[]i64]{ val: [i64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
|
||||
|
||||
assert json.encode(StructTypeOptional[[]u64]{}) == '{}'
|
||||
assert json.encode(StructTypeOptional[[]u64]{ val: [] }) == '{"val":[]}'
|
||||
assert json.encode(StructTypeOptional[[]u64]{ val: [u64(0)] }) == '{"val":[0]}'
|
||||
assert json.encode(StructTypeOptional[[]u64]{ val: [u64(1)] }) == '{"val":[1]}'
|
||||
assert json.encode(StructTypeOptional[[]u64]{ val: [u64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0,1,0,2,3,2,5,1]}'
|
||||
|
||||
assert json.encode(StructTypeOptional[[]f64]{}) == '{}'
|
||||
assert json.encode(StructTypeOptional[[]f64]{ val: [] }) == '{"val":[]}'
|
||||
assert json.encode(StructTypeOptional[[]f64]{ val: [f64(0)] }) == '{"val":[0.0]}'
|
||||
assert json.encode(StructTypeOptional[[]f64]{ val: [f64(1)] }) == '{"val":[1.0]}'
|
||||
assert json.encode(StructTypeOptional[[]f64]{ val: [f64(0), 1, 0, 2, 3, 2, 5, 1] }) == '{"val":[0.0,1.0,0.0,2.0,3.0,2.0,5.0,1.0]}'
|
||||
|
||||
assert json.encode(StructTypeOptional[[]bool]{}) == '{}'
|
||||
assert json.encode(StructTypeOptional[[]bool]{ val: [] }) == '{"val":[]}'
|
||||
assert json.encode(StructTypeOptional[[]bool]{ val: [true] }) == '{"val":[true]}'
|
||||
assert json.encode(StructTypeOptional[[]bool]{ val: [false] }) == '{"val":[false]}'
|
||||
assert json.encode(StructTypeOptional[[]bool]{ val: [false, true, false] }) == '{"val":[false,true,false]}'
|
||||
|
||||
array_of_struct := [StructType[bool]{
|
||||
val: true
|
||||
}, StructType[bool]{
|
||||
val: false
|
||||
}]
|
||||
assert json.encode(StructTypeOptional[[]StructType[bool]]{ val: array_of_struct }) == '{"val":[{"val":true},{"val":false}]}'
|
||||
}
|
||||
|
||||
fn test_alias() {
|
||||
|
@ -157,75 +157,58 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
|
||||
}
|
||||
$for field in U.fields {
|
||||
value := val.$(field.name)
|
||||
is_none := value.str() == 'Option(error: none)'
|
||||
if !is_none {
|
||||
mut json_name := ''
|
||||
for attr in field.attrs {
|
||||
if attr.contains('json: ') {
|
||||
json_name = attr.replace('json: ', '')
|
||||
break
|
||||
mut json_name := ''
|
||||
for attr in field.attrs {
|
||||
if attr.contains('json: ') {
|
||||
json_name = attr.replace('json: ', '')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
$if field.is_optional {
|
||||
is_none := value.str() == 'Option(error: none)'
|
||||
|
||||
if !is_none {
|
||||
e.encode_newline(level, mut wr)!
|
||||
if json_name != '' {
|
||||
e.encode_string(json_name, mut wr)!
|
||||
} else {
|
||||
e.encode_string(field.name, mut wr)!
|
||||
}
|
||||
}
|
||||
e.encode_newline(level, mut wr)!
|
||||
if json_name != '' {
|
||||
e.encode_string(json_name, mut wr)!
|
||||
} else {
|
||||
e.encode_string(field.name, mut wr)!
|
||||
}
|
||||
wr.write(json2.colon_bytes)!
|
||||
if e.newline != 0 {
|
||||
wr.write(json2.space_bytes)!
|
||||
}
|
||||
$if field.typ is string {
|
||||
e.encode_string(value.str(), mut wr)!
|
||||
} $else $if field.typ is time.Time {
|
||||
parsed_time := val.$(field.name) as time.Time
|
||||
e.encode_string(parsed_time.format_rfc3339(), mut wr)!
|
||||
} $else $if field.typ is bool || field.typ is f32 || field.typ is f64 || field.typ is i8
|
||||
|| field.typ is i16 || field.typ is int || field.typ is i64 || field.typ is u8
|
||||
|| field.typ is u16 || field.typ is u32 || field.typ is u64 {
|
||||
wr.write(value.str().bytes())!
|
||||
} $else $if field.typ is []string || field.typ is []bool || field.typ is []f32
|
||||
|| field.typ is []f64 || field.typ is []i8 || field.typ is []i16
|
||||
|| field.typ is []int || field.typ is []i64 || field.typ is []u8
|
||||
|| field.typ is []byte || field.typ is []u16 || field.typ is []u32
|
||||
|| field.typ is []u64 {
|
||||
e.encode_array(value, level, mut wr)!
|
||||
} $else {
|
||||
}
|
||||
$if field.typ is ?string {
|
||||
optional_value := val.$(field.name) as ?string
|
||||
e.encode_string(optional_value, mut wr)!
|
||||
} $else $if field.typ is ?bool {
|
||||
optional_value := val.$(field.name) as ?bool
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?f32 {
|
||||
optional_value := val.$(field.name) as ?f32
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?f64 {
|
||||
optional_value := val.$(field.name) as ?f64
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?i8 {
|
||||
optional_value := val.$(field.name) as ?i8
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?i16 {
|
||||
optional_value := val.$(field.name) as ?i16
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?int {
|
||||
optional_value := val.$(field.name) as ?int
|
||||
wr.write(Any(optional_value).int().str().bytes())!
|
||||
} $else $if field.typ is ?[]byte {
|
||||
optional_value := val.$(field.name) as ?[]byte
|
||||
e.encode_array(optional_value, level, mut wr)!
|
||||
} $else $if field.typ is ?[]int {
|
||||
optional_value := val.$(field.name) as ?[]int
|
||||
e.encode_array(optional_value, level, mut wr)!
|
||||
} $else $if field.typ is ?time.Time {
|
||||
optional_value := val.$(field.name) as ?time.Time
|
||||
parsed_time := optional_value as time.Time
|
||||
e.encode_string(parsed_time.format_rfc3339(), mut wr)!
|
||||
} $else {
|
||||
if field.unaliased_typ != field.typ {
|
||||
wr.write(json2.colon_bytes)!
|
||||
|
||||
if e.newline != 0 {
|
||||
wr.write(json2.space_bytes)!
|
||||
}
|
||||
|
||||
$if field.typ is ?string {
|
||||
optional_value := val.$(field.name) as ?string
|
||||
e.encode_string(optional_value, mut wr)!
|
||||
} $else $if field.typ is ?bool {
|
||||
optional_value := val.$(field.name) as ?bool
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?f32 {
|
||||
optional_value := val.$(field.name) as ?f32
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?f64 {
|
||||
optional_value := val.$(field.name) as ?f64
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?i8 {
|
||||
optional_value := val.$(field.name) as ?i8
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?i16 {
|
||||
optional_value := val.$(field.name) as ?i16
|
||||
wr.write(Any(optional_value).str().bytes())!
|
||||
} $else $if field.typ is ?int {
|
||||
optional_value := val.$(field.name) as ?int
|
||||
wr.write(Any(optional_value).int().str().bytes())!
|
||||
} $else $if field.typ is ?time.Time {
|
||||
optional_value := val.$(field.name) as ?time.Time
|
||||
parsed_time := optional_value as time.Time
|
||||
e.encode_string(parsed_time.format_rfc3339(), mut wr)!
|
||||
} $else $if field.is_array {
|
||||
e.encode_array(value, level + 1, mut wr)!
|
||||
} $else $if field.is_alias {
|
||||
match field.unaliased_typ {
|
||||
typeof[string]().idx {
|
||||
e.encode_string(value.str(), mut wr)!
|
||||
@ -236,67 +219,123 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
|
||||
wr.write(value.str().bytes())!
|
||||
}
|
||||
typeof[[]byte]().idx, typeof[[]int]().idx {
|
||||
e.encode_array(value, level, mut wr)!
|
||||
// FIXME - error: could not infer generic type `U` in call to `encode_array`
|
||||
// e.encode_array(value, level, mut wr)!
|
||||
}
|
||||
else {
|
||||
// e.encode_value_with_level(value, level + 1, mut wr)!
|
||||
}
|
||||
}
|
||||
} $else {
|
||||
return error('type ${typeof(val).name} cannot be array encoded')
|
||||
}
|
||||
}
|
||||
|
||||
if i < fields_len - 1 {
|
||||
wr.write(json2.comma_bytes)!
|
||||
} $else {
|
||||
e.encode_newline(level, mut wr)!
|
||||
if json_name != '' {
|
||||
e.encode_string(json_name, mut wr)!
|
||||
} else {
|
||||
e.encode_string(field.name, mut wr)!
|
||||
}
|
||||
wr.write(json2.colon_bytes)!
|
||||
|
||||
if e.newline != 0 {
|
||||
wr.write(json2.space_bytes)!
|
||||
}
|
||||
|
||||
$if field.typ is string {
|
||||
e.encode_string(value.str(), mut wr)!
|
||||
} $else $if field.typ is time.Time {
|
||||
parsed_time := val.$(field.name) as time.Time
|
||||
e.encode_string(parsed_time.format_rfc3339(), mut wr)!
|
||||
} $else $if field.typ is bool || field.typ is f32 || field.typ is f64 || field.typ is i8
|
||||
|| field.typ is i16 || field.typ is int || field.typ is i64 || field.typ is u8
|
||||
|| field.typ is u16 || field.typ is u32 || field.typ is u64 {
|
||||
wr.write(value.str().bytes())!
|
||||
} $else $if field.is_array {
|
||||
e.encode_array(value, level + 1, mut wr)!
|
||||
} $else $if field.is_struct {
|
||||
e.encode_struct(value, level + 1, mut wr)!
|
||||
} $else $if field.is_alias {
|
||||
match field.unaliased_typ {
|
||||
typeof[string]().idx {
|
||||
e.encode_string(value.str(), mut wr)!
|
||||
}
|
||||
typeof[bool]().idx, typeof[f32]().idx, typeof[f64]().idx, typeof[i8]().idx,
|
||||
typeof[i16]().idx, typeof[int]().idx, typeof[i64]().idx, typeof[u8]().idx,
|
||||
typeof[u16]().idx, typeof[u32]().idx, typeof[u64]().idx {
|
||||
wr.write(value.str().bytes())!
|
||||
}
|
||||
typeof[[]byte]().idx, typeof[[]int]().idx {
|
||||
// FIXME - error: could not infer generic type `U` in call to `encode_array`
|
||||
// e.encode_array(value, level, mut wr)!
|
||||
}
|
||||
else {
|
||||
// e.encode_value_with_level(value, level + 1, mut wr)!
|
||||
}
|
||||
}
|
||||
} $else {
|
||||
return error('type ${typeof(val).name} cannot be array encoded')
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
if i < fields_len - 1 {
|
||||
wr.write(json2.comma_bytes)!
|
||||
}
|
||||
i++
|
||||
}
|
||||
e.encode_newline(level - 1, mut wr)!
|
||||
wr.write([u8(`}`)])!
|
||||
}
|
||||
|
||||
fn (e &Encoder) encode_array[U](val U, level int, mut wr io.Writer) ! {
|
||||
$if U is $Array {
|
||||
wr.write([u8(`[`)])!
|
||||
for i in 0 .. val.len {
|
||||
e.encode_newline(level, mut wr)!
|
||||
fn (e &Encoder) encode_array[U](val []U, level int, mut wr io.Writer) ! {
|
||||
wr.write([u8(`[`)])!
|
||||
for i in 0 .. val.len {
|
||||
e.encode_newline(level, mut wr)!
|
||||
|
||||
$if U is []string {
|
||||
e.encode_any(val[i], level + 1, mut wr)!
|
||||
} $else $if U is []bool {
|
||||
e.encode_any(bool(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []f32 {
|
||||
e.encode_any(f32(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []f64 {
|
||||
e.encode_any(f64(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []i8 {
|
||||
e.encode_any(i8(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []i16 {
|
||||
e.encode_any(i16(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []int {
|
||||
e.encode_any(int(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []i64 {
|
||||
e.encode_any(i64(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []u8 {
|
||||
e.encode_any(u8(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []byte {
|
||||
e.encode_any(u8(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []u16 {
|
||||
e.encode_any(u16(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []u32 {
|
||||
e.encode_any(u32(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is []u64 {
|
||||
e.encode_any(u64(val[i]), level + 1, mut wr)!
|
||||
}
|
||||
if i < val.len - 1 {
|
||||
wr.write(json2.comma_bytes)!
|
||||
}
|
||||
$if U is string {
|
||||
e.encode_any(val[i], level + 1, mut wr)!
|
||||
} $else $if U is bool {
|
||||
e.encode_any(bool(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is f32 {
|
||||
e.encode_any(f32(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is f64 {
|
||||
e.encode_any(f64(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is i8 {
|
||||
e.encode_any(i8(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is i16 {
|
||||
e.encode_any(i16(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is int {
|
||||
e.encode_any(int(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is i64 {
|
||||
e.encode_any(i64(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is u8 {
|
||||
e.encode_any(u8(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is byte {
|
||||
e.encode_any(u8(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is u16 {
|
||||
e.encode_any(u16(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is u32 {
|
||||
e.encode_any(u32(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is u64 {
|
||||
e.encode_any(u64(val[i]), level + 1, mut wr)!
|
||||
} $else $if U is $Array {
|
||||
// FIXME - error: could not infer generic type `U` in call to `encode_array`
|
||||
// e.encode_array(val[i], level + 1, mut wr)!
|
||||
} $else $if U is $Struct {
|
||||
e.encode_struct(val[i], level + 1, mut wr)!
|
||||
} $else $if U is $Enum {
|
||||
e.encode_any(i64(val[i]), level + 1, mut wr)!
|
||||
} $else {
|
||||
return error('type ${typeof(val).name} cannot be array encoded')
|
||||
}
|
||||
if i < val.len - 1 {
|
||||
wr.write(json2.comma_bytes)!
|
||||
}
|
||||
e.encode_newline(level - 1, mut wr)!
|
||||
wr.write([u8(`]`)])!
|
||||
} $else {
|
||||
return error('encoded array value is not an array')
|
||||
}
|
||||
|
||||
e.encode_newline(level - 1, mut wr)!
|
||||
wr.write([u8(`]`)])!
|
||||
}
|
||||
|
||||
// str returns the JSON string representation of the `map[string]Any` type.
|
||||
|
Loading…
Reference in New Issue
Block a user