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

x.json2: fix: #16975 (#16983)

* fix: #16975

* test

* Update vlib/x/json2/json2.v

Co-authored-by: Delyan Angelov <delian66@gmail.com>

* minor refactor

Co-authored-by: Delyan Angelov <delian66@gmail.com>
This commit is contained in:
Hitalo Souza 2023-01-15 17:09:02 -03:00 committed by GitHub
parent bfb47005c8
commit 7db7951bd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 47 deletions

View File

@ -23,39 +23,51 @@ pub fn decode[T](src string) !T {
res := raw_decode(src)!.as_map() res := raw_decode(src)!.as_map()
mut typ := T{} mut typ := T{}
$for field in T.fields { $for field in T.fields {
mut json_name := field.name
for attr in field.attrs {
if attr.contains('json: ') {
json_name = attr.replace('json: ', '')
break
}
}
$if field.typ is u8 { $if field.typ is u8 {
typ.$(field.name) = u8(res[field.name]!.u64()) typ.$(field.name) = res[json_name]!.u64()
} $else $if field.typ is u16 { } $else $if field.typ is u16 {
typ.$(field.name) = u16(res[field.name]!.u64()) typ.$(field.name) = res[json_name]!.u64()
} $else $if field.typ is u32 { } $else $if field.typ is u32 {
typ.$(field.name) = u32(res[field.name]!.u64()) typ.$(field.name) = res[json_name]!.u64()
} $else $if field.typ is u64 { } $else $if field.typ is u64 {
typ.$(field.name) = res[field.name]!.u64() typ.$(field.name) = res[json_name]!.u64()
} $else $if field.typ is int { } $else $if field.typ is int {
typ.$(field.name) = res[field.name]!.int() typ.$(field.name) = res[json_name]!.int()
} $else $if field.typ is i8 { } $else $if field.typ is i8 {
typ.$(field.name) = i8(res[field.name]!.i64()) typ.$(field.name) = res[json_name]!.int()
} $else $if field.typ is i16 { } $else $if field.typ is i16 {
typ.$(field.name) = i16(res[field.name]!.i64()) typ.$(field.name) = res[json_name]!.int()
} $else $if field.typ is i32 { } $else $if field.typ is i32 {
// typ.$(field.name) = res[field.name]!.i32() // typ.$(field.name) = res[field.name]!.i32()
} $else $if field.typ is i64 { } $else $if field.typ is i64 {
typ.$(field.name) = res[field.name]!.i64() typ.$(field.name) = res[json_name]!.i64()
} $else $if field.typ is f32 { } $else $if field.typ is f32 {
typ.$(field.name) = res[field.name]!.f32() typ.$(field.name) = res[json_name]!.f32()
} $else $if field.typ is f64 { } $else $if field.typ is f64 {
typ.$(field.name) = res[field.name]!.f64() typ.$(field.name) = res[json_name]!.f64()
} $else $if field.typ is bool { } $else $if field.typ is bool {
typ.$(field.name) = res[field.name]!.bool() typ.$(field.name) = res[json_name]!.bool()
} $else $if field.typ is string { } $else $if field.typ is string {
typ.$(field.name) = res[field.name]!.str() typ.$(field.name) = res[json_name]!.str()
} $else $if field.typ is time.Time { } $else $if field.typ is time.Time {
typ.$(field.name) = res[field.name]!.to_time()! typ.$(field.name) = res[field.name]!.to_time()!
} $else $if field.is_array { } $else $if field.is_array {
// typ.$(field.name) = res[field.name]!.arr() // typ.$(field.name) = res[field.name]!.arr()
} $else $if field.is_struct { } $else $if field.is_struct {
} $else $if field.is_enum { } $else $if field.is_enum {
typ.$(field.name) = res[field.name]!.int() typ.$(field.name) = if key := res[field.name] {
key.int()
} else {
res[json_name]!.int()
}
} $else $if field.is_alias { } $else $if field.is_alias {
} $else $if field.is_map { } $else $if field.is_map {
} $else { } $else {

View File

@ -1,5 +1,5 @@
import x.json2 as json import x.json2 as json
// import time import time
enum JobTitle { enum JobTitle {
manager manager
@ -54,12 +54,12 @@ fn test_simple() {
// currency_id string [json: currencyId] = currency_id // currency_id string [json: currencyId] = currency_id
// } // }
// struct User2 { struct User2 {
// mut: mut:
// age int age int
// nums []int nums []int
// reg_date time.Time reg_date time.Time
// } }
// // User struct needs to be `pub mut` for now in order to access and manipulate values // // User struct needs to be `pub mut` for now in order to access and manipulate values
struct User { struct User {
@ -72,6 +72,34 @@ pub mut:
pets string [json: 'pet_animals'; raw] pets string [json: 'pet_animals'; raw]
} }
fn test_parse_user() {
s := '{"age": 10, "nums": [1,2,3], "type": 1, "lastName": "Johnson", "IsRegistered": true, "pet_animals": {"name": "Bob", "animal": "Dog"}}'
u := json.decode[User](s)!
assert u.age == 10
assert u.last_name == 'Johnson'
assert u.is_registered == true
// assert u.nums.len == 3
// assert u.nums[0] == 1
// assert u.nums[1] == 2
// assert u.nums[2] == 3
assert u.typ == 1
assert u.pets == '{"name":"Bob","animal":"Dog"}'
}
fn test_encode_decode_time() {
user := User2{
age: 25
reg_date: time.new_time(year: 2020, month: 12, day: 22, hour: 7, minute: 23)
}
s := json.encode(user)
assert s.contains('"reg_date":"2020-12-22T07:23:00.000Z"')
user2 := json.decode[User2](s)!
assert user2.reg_date.str() == '2020-12-22 07:23:00'
}
fn (mut u User) foo() string { fn (mut u User) foo() string {
return json.encode(u) return json.encode(u)
} }

View File

@ -112,33 +112,6 @@ pub mut:
pets string [json: 'pet_animals'; raw] pets string [json: 'pet_animals'; raw]
} }
fn test_parse_user() {
s := '{"age": 10, "nums": [1,2,3], "type": 1, "lastName": "Johnson", "IsRegistered": true, "pet_animals": {"name": "Bob", "animal": "Dog"}}'
u2 := json.decode[User2](s)!
u := json.decode[User](s)!
assert u.age == 10
assert u.last_name == 'Johnson'
assert u.is_registered == true
assert u.nums.len == 3
assert u.nums[0] == 1
assert u.nums[1] == 2
assert u.nums[2] == 3
assert u.typ == 1
assert u.pets == '{"name":"Bob","animal":"Dog"}'
}
//! BUGFIX - .from_json(res)
fn test_encode_decode_time() {
user := User2{
age: 25
reg_date: time.new_time(year: 2020, month: 12, day: 22, hour: 7, minute: 23)
}
s := json.encode(user)
assert s.contains('"reg_date":1608621780')
user2 := json.decode[User2](s)!
assert user2.reg_date.str() == '2020-12-22 07:23:00'
}
struct City { struct City {
name string name string
} }