x.json2.decoder2: support aliases fully (#22608)

This commit is contained in:
Hitalo Souza 2024-10-21 10:43:27 -04:00 committed by GitHub
parent f31ba78de8
commit 8e3cd702a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 31 deletions

View file

@ -606,13 +606,13 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
val = string_buffer.bytestr() val = string_buffer.bytestr()
} }
} $else $if T is $sumtype { } $else $if T.unaliased_typ is $sumtype {
$for v in val.variants { $for v in val.variants {
if val is v { if val is v {
decoder.decode_value(val) decoder.decode_value(val)
} }
} }
} $else $if T is time.Time { } $else $if T.unaliased_typ is time.Time {
time_info := decoder.current_node.value time_info := decoder.current_node.value
if time_info.value_kind == .string_ { if time_info.value_kind == .string_ {
@ -621,7 +621,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
val = time.parse_rfc3339(string_time) or { time.Time{} } val = time.parse_rfc3339(string_time) or { time.Time{} }
} }
} $else $if T is $map { } $else $if T.unaliased_typ is $map {
map_info := decoder.current_node.value map_info := decoder.current_node.value
if map_info.value_kind == .object { if map_info.value_kind == .object {
@ -657,7 +657,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
val[key] = map_value val[key] = map_value
} }
} }
} $else $if T is $array { } $else $if T.unaliased_typ is $array {
array_info := decoder.current_node.value array_info := decoder.current_node.value
if array_info.value_kind == .array { if array_info.value_kind == .array {
@ -682,7 +682,7 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
val << array_element val << array_element
} }
} }
} $else $if T is $struct { } $else $if T.unaliased_typ is $struct {
struct_info := decoder.current_node.value struct_info := decoder.current_node.value
if struct_info.value_kind == .object { if struct_info.value_kind == .object {
@ -722,13 +722,13 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
} }
} }
} }
} $else $if T is bool { } $else $if T.unaliased_typ is bool {
value_info := decoder.current_node.value value_info := decoder.current_node.value
unsafe { unsafe {
val = vmemcmp(decoder.json.str + value_info.position, 'true'.str, 4) == 0 val = vmemcmp(decoder.json.str + value_info.position, 'true'.str, 4) == 0
} }
} $else $if T in [$int, $float, $enum] { } $else $if T.unaliased_typ in [$int, $float, $enum] {
value_info := decoder.current_node.value value_info := decoder.current_node.value
if value_info.value_kind == .number { if value_info.value_kind == .number {
@ -897,7 +897,7 @@ fn generate_unicode_escape_sequence(escape_sequence_byte []u8) ![]u8 {
// NOTE: This aims works with not new memory allocated data, to more efficient use `vbytes` before // NOTE: This aims works with not new memory allocated data, to more efficient use `vbytes` before
@[direct_array_access; unsafe] @[direct_array_access; unsafe]
pub fn string_buffer_to_generic_number[T](result &T, data []u8) { pub fn string_buffer_to_generic_number[T](result &T, data []u8) {
$if T is $int { $if T.unaliased_typ is $int {
mut is_negative := false mut is_negative := false
for ch in data { for ch in data {
if ch == `-` { if ch == `-` {
@ -910,7 +910,7 @@ pub fn string_buffer_to_generic_number[T](result &T, data []u8) {
if is_negative { if is_negative {
*result *= -1 *result *= -1
} }
} $else $if T is $float { } $else $if T.unaliased_typ is $float {
mut is_negative := false mut is_negative := false
mut decimal_seen := false mut decimal_seen := false
mut decimal_divider := int(1) mut decimal_divider := int(1)
@ -937,7 +937,7 @@ pub fn string_buffer_to_generic_number[T](result &T, data []u8) {
if is_negative { if is_negative {
*result *= -1 *result *= -1
} }
} $else $if T is $enum { } $else $if T.unaliased_typ is $enum {
// Convert the string to an integer // Convert the string to an integer
enumeration := 0 enumeration := 0
for ch in data { for ch in data {
@ -945,20 +945,6 @@ pub fn string_buffer_to_generic_number[T](result &T, data []u8) {
enumeration = enumeration * 10 + digit enumeration = enumeration * 10 + digit
} }
*result = T(enumeration) *result = T(enumeration)
} $else $if T is $alias {
$if T.unaliased_typ in [$int, $enum] {
// alias_value := 0
// string_buffer_to_generic_number(&alias_value, data)
// *result = alias_value
panic('unsupported type ${typeof[T]().name}')
} $else $if T.unaliased_typ is $float {
// alias_value := 0.0
// string_buffer_to_generic_number(&alias_value, data)
// *result = alias_value
panic('unsupported type ${typeof[T]().name}')
} $else {
panic('unsupported type ${typeof[T]().name}')
}
} $else { } $else {
panic('unsupported type ${typeof[T]().name}') panic('unsupported type ${typeof[T]().name}')
} }

View file

@ -20,6 +20,8 @@ pub struct Stru2 {
} }
type SumTypes = StructType[string] | bool | int | string | time.Time type SumTypes = StructType[string] | bool | int | string | time.Time
type StringAlias = string
type IntAlias = int
enum Enum { enum Enum {
a a
@ -167,4 +169,20 @@ fn main() {
} }
b.measure('decoder2.decode[string](\'"abcdefghijklimnopqrstuv"\')!') b.measure('decoder2.decode[string](\'"abcdefghijklimnopqrstuv"\')!')
// alias **********************************************************
println('\n***alias***')
for i := 0; i < max_iterations; i++ {
_ := decoder2.decode[IntAlias]('2')!
}
b.measure('decoder2.decode[IntAlias](2)!')
for i := 0; i < max_iterations; i++ {
_ := decoder2.decode[StringAlias]('"abcdefghijklimnopqrstuv"')!
}
b.measure('decoder2.decode[StringAlias](\'"abcdefghijklimnopqrstuv"\')!')
} }

View file

@ -55,15 +55,19 @@ fn test_types() {
assert json.decode[StructType[Enumerates]]('{"val": 0}')!.val == Enumerates.a assert json.decode[StructType[Enumerates]]('{"val": 0}')!.val == Enumerates.a
assert json.decode[StructType[Enumerates]]('{"val": 1}')!.val == Enumerates.b assert json.decode[StructType[Enumerates]]('{"val": 1}')!.val == Enumerates.b
// assert json.decode[StructType[IntAlias]]('{"val": 2}')!.val == IntAlias(2)
assert json.decode[StructType[StringAlias]]('{"val": "2"}')!.val == StringAlias('2') assert json.decode[StructType[StringAlias]]('{"val": "2"}')!.val == StringAlias('2')
assert json.decode[StructType[BoolAlias]]('{"val": true}')!.val == BoolAlias(true)
assert json.decode[StructType[IntAlias]]('{"val": 2}')!.val == IntAlias(2)
assert json.decode[StructType[TimeAlias]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val == TimeAlias(fixed_time)
assert json.decode[StructType[TimeAlias]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.unix() == fixed_time.unix()
assert json.decode[StructType[StructAlias]]('{"val": {"val": 2}}')!.val == StructAlias(StructType[int]{
val: 2
})
assert json.decode[StructAlias]('{"val": 2}')!.val == 2
assert json.decode[StructType[EnumAlias]]('{"val": 0}')!.val == EnumAlias(Enumerates.a)
assert json.decode[StructType[EnumAlias]]('{"val": 1}')!.val == EnumAlias(Enumerates.b)
assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.year == fixed_time.year assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val == fixed_time
assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.month == fixed_time.month
assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.day == fixed_time.day
assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.hour == fixed_time.hour
assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.minute == fixed_time.minute
assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.second == fixed_time.second
assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.unix() == fixed_time.unix() assert json.decode[StructType[time.Time]]('{"val": "2022-03-11T13:54:25.000Z"}')!.val.unix() == fixed_time.unix()
} }