diff --git a/vlib/x/json2/any_test.v b/vlib/x/json2/any_test.v index 0e259fe67d..7a475c38fa 100644 --- a/vlib/x/json2/any_test.v +++ b/vlib/x/json2/any_test.v @@ -107,11 +107,11 @@ fn test_bool() { // valid conversions assert sample_data['bool'] or { 0 }.bool() == false assert json.Any('true').bool() == true - // invalid conversions assert sample_data['int'] or { 0 }.bool() == true assert sample_data['i64'] or { 0 }.bool() == true assert sample_data['f32'] or { 0 }.bool() == true assert sample_data['f64'] or { 0 }.bool() == true + // invalid conversions assert sample_data['null'] or { 0 }.bool() == false assert sample_data['arr'] or { 0 }.bool() == false assert sample_data['obj'] or { 0 }.bool() == false diff --git a/vlib/x/json2/decode_struct_test.v b/vlib/x/json2/decode_struct_test.v index 4bdb6c67b6..3db6cdd697 100644 --- a/vlib/x/json2/decode_struct_test.v +++ b/vlib/x/json2/decode_struct_test.v @@ -1,4 +1,15 @@ 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: 0 +} type StringAlias = string type BoolAlias = bool @@ -6,6 +17,15 @@ type IntAlias = int type SumTypes = bool | int | string +enum Enumerates { + a + b + c + d + e = 99 + f +} + struct StructType[T] { mut: val T diff --git a/vlib/x/json2/encode_struct_test.v b/vlib/x/json2/encode_struct_test.v index 3835eb8257..d300b0dec9 100644 --- a/vlib/x/json2/encode_struct_test.v +++ b/vlib/x/json2/encode_struct_test.v @@ -1,4 +1,15 @@ 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: 1647017665 +} type StringAlias = string type BoolAlias = bool @@ -6,6 +17,15 @@ type IntAlias = int type SumTypes = bool | int | string +enum Enumerates { + a + b + c + d + e = 99 + f +} + struct StructType[T] { mut: val T @@ -33,6 +53,9 @@ fn test_types() { assert json.encode(StructType[int]{}) == '{"val":0}' assert json.encode(StructType[int]{ val: 0 }) == '{"val":0}' assert json.encode(StructType[int]{ val: 1 }) == '{"val":1}' + + 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"}' } fn test_optional_types() { @@ -50,6 +73,9 @@ fn test_optional_types() { assert json.encode(StructTypeOptional[int]{}) == '{"val":0}' assert json.encode(StructTypeOptional[int]{ val: 0 }) == '{"val":0}' assert json.encode(StructTypeOptional[int]{ val: 1 }) == '{"val":1}' + + assert json.encode(StructTypeOptional[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"}' } fn test_array() { diff --git a/vlib/x/json2/encoder.v b/vlib/x/json2/encoder.v index 2919b711eb..1bf6c9ad31 100644 --- a/vlib/x/json2/encoder.v +++ b/vlib/x/json2/encoder.v @@ -5,6 +5,7 @@ module json2 import io import strings +import time // Encoder encodes the an `Any` type into JSON representation. // It provides parameters in order to change the end result. @@ -112,6 +113,7 @@ fn (e &Encoder) encode_any(val Any, level int, mut wr io.Writer) ! { e.encode_newline(level - 1, mut wr)! wr.write([u8(`]`)])! } + time.Time {} Null { wr.write(json2.null_in_bytes)! } @@ -176,6 +178,9 @@ 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)! + } $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 { @@ -215,6 +220,10 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! { } $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 { match field.unaliased_typ { diff --git a/vlib/x/json2/json2_test.v b/vlib/x/json2/json2_test.v index a27a5f735b..ae5d13b02d 100644 --- a/vlib/x/json2/json2_test.v +++ b/vlib/x/json2/json2_test.v @@ -1,5 +1,4 @@ import x.json2 as json -import time enum JobTitle { manager diff --git a/vlib/x/json2/types.v b/vlib/x/json2/types.v index 6e5dc50ddb..9a96c93d19 100644 --- a/vlib/x/json2/types.v +++ b/vlib/x/json2/types.v @@ -1,5 +1,7 @@ module json2 +import time + // `Any` is a sum type that lists the possible types to be decoded and used. pub type Any = Null | []Any @@ -12,6 +14,7 @@ pub type Any = Null | int | map[string]Any | string + | time.Time | u16 | u32 | u64