diff --git a/vlib/x/json2/encode_struct_test.v b/vlib/x/json2/encode_struct_test.v index 23d315d4d1..e13c2111b7 100644 --- a/vlib/x/json2/encode_struct_test.v +++ b/vlib/x/json2/encode_struct_test.v @@ -16,6 +16,7 @@ type BoolAlias = bool type IntAlias = int type TimeAlias = time.Time type StructAlias = StructType[int] +type EnumAlias = Enumerates type SumTypes = bool | int | string @@ -99,10 +100,6 @@ fn test_option_types() { }) == '{"val":{"val":1}}' assert json.encode(StructTypeOption[Enumerates]{}) == '{}' - // assert json.encode(StructTypeOption[Enumerates]{ val: Enumerates.a }) == '{"val":0}' - // assert json.encode(StructTypeOption[Enumerates]{ val: Enumerates.d }) == '{"val":3}' - // assert json.encode(StructTypeOption[Enumerates]{ val: Enumerates.e }) == '{"val":99}' - // assert json.encode(StructTypeOption[Enumerates]{ val: Enumerates.f }) == '{"val":100}' } fn test_array() { diff --git a/vlib/x/json2/encode_struct_todo_test.vv b/vlib/x/json2/encode_struct_todo_test.vv index 9b97eab775..5106723dfb 100644 --- a/vlib/x/json2/encode_struct_todo_test.vv +++ b/vlib/x/json2/encode_struct_todo_test.vv @@ -1,11 +1,34 @@ import x.json2 as json +import time + +const fixed_time = time.Time{ + year: 2022 + month: 3 + day: 11 + hour: 13 + minute: 54 + second: 25 + unix: 1647006865 +} type StringAlias = string type BoolAlias = bool type IntAlias = int +type TimeAlias = time.Time +type StructAlias = StructType[int] +type EnumAlias = Enumerates type SumTypes = bool | int | string +enum Enumerates { + a + b + c + d + e = 99 + f +} + struct StructType[T] { mut: val T @@ -21,6 +44,13 @@ mut: val &T } +fn test_option_types() { + assert json.encode(StructTypeOption[Enumerates]{ val: Enumerates.a }) == '{"val":0}' + assert json.encode(StructTypeOption[Enumerates]{ val: Enumerates.d }) == '{"val":3}' + assert json.encode(StructTypeOption[Enumerates]{ val: Enumerates.e }) == '{"val":99}' + assert json.encode(StructTypeOption[Enumerates]{ val: Enumerates.f }) == '{"val":100}' +} + fn test_option_alias() { assert json.encode(StructTypeOption[BoolAlias]{ val: none }) == '{}' assert json.encode(StructTypeOption[BoolAlias]{}) == '{"val":false}' @@ -31,11 +61,24 @@ fn test_option_alias() { assert json.encode(StructTypeOption[IntAlias]{}) == '{"val":0}' assert json.encode(StructTypeOption[IntAlias]{ val: 0 }) == '{"val":0}' assert json.encode(StructTypeOption[IntAlias]{ val: 1 }) == '{"val":1}' + + assert json.encode(StructTypeOption[EnumAlias]{}) == '{"val":0}' + assert json.encode(StructTypeOption[EnumAlias]{ val: Enumerates.a }) == '{"val":0}' + assert json.encode(StructTypeOption[EnumAlias]{ val: Enumerates.d }) == '{"val":3}' + assert json.encode(StructTypeOption[EnumAlias]{ val: Enumerates.e }) == '{"val":99}' + assert json.encode(StructTypeOption[EnumAlias]{ val: Enumerates.f }) == '{"val":100}' +} + +fn test_alias() { + assert json.encode(StructType[EnumAlias]{}) == '{"val":0}' + assert json.encode(StructType[EnumAlias]{ val: Enumerates.a }) == '{"val":0}' + assert json.encode(StructType[EnumAlias]{ val: Enumerates.d }) == '{"val":3}' + assert json.encode(StructType[EnumAlias]{ val: Enumerates.e }) == '{"val":99}' + assert json.encode(StructType[EnumAlias]{ val: Enumerates.f }) == '{"val":100}' } fn test_sumtypes() { - assert json.encode(StructType[SumTypes]{}) == '{}' // REVIEW - + assert json.encode(StructType[SumTypes]{}) == '{}' assert json.encode(StructType[SumTypes]{ val: '' }) == '{"val":""}' assert json.encode(StructType[SumTypes]{ val: 'a' }) == '{"val":"a"}' @@ -44,6 +87,12 @@ fn test_sumtypes() { assert json.encode(StructType[SumTypes]{ val: 0 }) == '{"val":0}' assert json.encode(StructType[SumTypes]{ val: 1 }) == '{"val":1}' + + assert json.encode(StructType[StructType[SumTypes]]{ + val: StructType[SumTypes]{ + val: 1 + } + }) == '{"val":{"val":1}}' } fn test_option_sumtypes() { diff --git a/vlib/x/json2/encoder.v b/vlib/x/json2/encoder.v index e250a6dcd0..6b3ca359fb 100644 --- a/vlib/x/json2/encoder.v +++ b/vlib/x/json2/encoder.v @@ -234,38 +234,71 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! { } $if field.typ is string { - e.encode_string(value.str(), mut wr)! + e.encode_string(val.$(field.name).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 in [bool, $Float, $Int] { - wr.write(value.str().bytes())! + wr.write(val.$(field.name).str().bytes())! } $else $if field.is_array { + // TODO - replace for `field.typ is $Array` e.encode_array(value, level + 1, mut wr)! - } $else $if field.is_struct { + } $else $if field.typ is $Array { + // e.encode_array(value, level + 1, mut wr)! // FIXME - error: could not infer generic type `U` in call to `encode_array` + } $else $if field.typ is $Struct { e.encode_struct(value, level + 1, mut wr)! } $else $if field.is_enum { + // TODO - replace for `field.typ is $Enum` wr.write(int(val.$(field.name)).str().bytes())! - } $else $if field.is_alias { + } $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") + // } + // } + } $else $if field.typ is $Alias { $if field.unaliased_typ is string { - e.encode_string(value.str(), mut wr)! + e.encode_string(val.$(field.name).str(), mut wr)! } $else $if field.unaliased_typ is time.Time { parsed_time := val.$(field.name) as time.Time e.encode_string(parsed_time.format_rfc3339(), mut wr)! } $else $if field.unaliased_typ in [bool, $Float, $Int] { - wr.write(value.str().bytes())! - } - // FIXME - // $else $if field.unaliased_typ is $Array { - // // e.encode_array(value, level + 1, mut wr)! - // } $else $if field.unaliased_typ is $Struct { - // // e.encode_struct(value, level + 1, mut wr)! - // } $else $if field.unaliased_typ is $Enum { - // // wr.write(int(val.$(field.name)).str().bytes())! - // } - $else { + wr.write(val.$(field.name).str().bytes())! + } $else $if field.unaliased_typ is $Array { + // e.encode_array(val.$(field.name), level + 1, mut wr)! // FIXME - error: could not infer generic type `U` in call to `encode_array` + } $else $if field.unaliased_typ is $Struct { + // e.encode_struct(val.$(field.name), level + 1, mut wr)! // FIXME - error: cannot use `BoolAlias` as `StringAlias` in argument 1 to `x.json2.Encoder.encode_struct` e.encode_struct(value, level + 1, mut wr)! - // return error('the alias ${typeof(val).name} cannot be encoded') + } $else $if field.unaliased_typ is $Enum { + // enum_value := val.$(field.name) + // dump(int(val.$(field.name))) // FIXME + // dump(val.$(field.name).int()) // FIXME - error: unknown method or field: `BoolAlias.int` + // dump(val.$(field.name).int()) // FIXME - error: cannot convert 'enum ' to 'struct string' + + // wr.write(val.$(field.name).int().str().bytes())! // FIXME - error: unknown method or field: `BoolAlias.int` + } $else $if field.unaliased_typ is $Sumtype { + } $else { + return error('the alias ${typeof(val).name} cannot be encoded') } } $else { return error('type ${typeof(val).name} cannot be array encoded')