1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

json2: encode sumtype (#17041)

This commit is contained in:
Hitalo Souza 2023-01-21 15:26:55 -03:00 committed by GitHub
parent 1d51f3109f
commit 0ac6ba9354
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 33 deletions

View File

@ -18,7 +18,7 @@ type TimeAlias = time.Time
type StructAlias = StructType[int]
type EnumAlias = Enumerates
type SumTypes = bool | int | string
type SumTypes = StructType[string] | bool | int | string | time.Time
enum Enumerates {
a
@ -222,3 +222,33 @@ fn test_alias() {
assert json.encode(StructType[StructAlias]{ val: StructType[int]{0} }) == '{"val":{"val":0}}'
assert json.encode(StructType[StructAlias]{ val: StructType[int]{1} }) == '{"val":{"val":1}}'
}
fn test_sumtypes() {
assert json.encode(StructType[SumTypes]{}) == '{}'
assert json.encode(StructType[SumTypes]{ val: '' }) == '{"val":""}'
assert json.encode(StructType[SumTypes]{ val: 'a' }) == '{"val":"a"}'
assert json.encode(StructType[SumTypes]{ val: false }) == '{"val":false}'
assert json.encode(StructType[SumTypes]{ val: true }) == '{"val":true}'
assert json.encode(StructType[SumTypes]{ val: 0 }) == '{"val":0}'
assert json.encode(StructType[SumTypes]{ val: 1 }) == '{"val":1}'
assert json.encode(StructType[SumTypes]{ val: fixed_time }) == '{"val":2022-03-11T13:54:25.000Z}'
assert json.encode(StructType[StructType[SumTypes]]{
val: StructType[SumTypes]{
val: 1
}
}) == '{"val":{"val":1}}'
// assert json.encode(StructType[SumTypes]{ val: StructType[string]{
// val: '111111'
// } }) == '{"val":1}'
assert json.encode(StructType[StructType[SumTypes]]{
val: StructType[SumTypes]{
val: 1
}
}) == '{"val":{"val":1}}'
}

View File

@ -221,6 +221,8 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
}
}
} $else {
is_none := val.$(field.name).str() == 'unknown sum type value'
if !is_none {
e.encode_newline(level, mut wr)!
if json_name != '' {
e.encode_string(json_name, mut wr)!
@ -232,6 +234,7 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
if e.newline != 0 {
wr.write(json2.space_bytes)!
}
}
$if field.typ is string {
e.encode_string(val.$(field.name).str(), mut wr)!
@ -254,29 +257,65 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
} $else $if field.typ is $Enum {
// wr.write(int(val.$(field.name)).str().bytes())! // FIXME - error: cannot cast string to `int`, use `val.$field.name.int()` instead.
} $else $if field.typ is $Sumtype {
// // FIXME - error: cannot match `bool` with `string`
// match value {
// string {
// println(val.$(field.name))
// }
// bool {
// }
// i8, i16, int, i64 {
// }
// u8, u16, u32, u64 {
// }
// f32, f64 {
// }
// map[string]Any {
// }
// []Any {
// }
// time.Time {}
// Null {
// } else {
// dump("elsa")
// }
// }
// dump(val.$(field.name).str())
// dump(is_none)
sum_type_value := value.str()#[typeof(val.$(field.name)).name.len + 1..-1]
is_string := sum_type_value[0] == "'"[0]
// mut is_struct := false
// mut is_sumtype := false
// mut is_enum := false
// mut is_array := false
match sum_type_value[0] {
`0`...`9` {
if sum_type_value.contains_any(' /:-') {
date_time_str := time.parse(sum_type_value)!
wr.write(date_time_str.format_rfc3339().bytes())!
} else {
wr.write(sum_type_value.bytes())!
}
}
`A`...`Z` {
// SumTypes(0)
if sum_type_value.contains('(') {
if !sum_type_value.all_before('(').contains_any(' "\'[') {
// is_sumtype = true
}
}
// StructType{
// StructType[int]{
if sum_type_value.contains('{') {
if !sum_type_value.all_before('{').contains_any(' "\'') {
// is_struct = true
// TODO
// e.encode_struct_from_sumtype(value, level + 1, mut wr)!
}
}
}
`a`...`z` {
if sum_type_value in ['true', 'false'] {
wr.write(sum_type_value.bytes())!
} else {
// is_enum = true
}
}
else {
// dump('else')
}
}
// dump(sum_type_value)
// dump(is_none)
// dump(is_string)
// dump(is_struct)
// dump(is_sumtype)
// dump(is_enum)
// dump(is_array)
if is_string {
e.encode_string(sum_type_value#[1..-1], mut wr)!
}
} $else $if field.typ is $Alias {
$if field.unaliased_typ is string {
e.encode_string(val.$(field.name).str(), mut wr)!