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

x.json2: add json2.map_from(t T) (#16797)

This commit is contained in:
Hitalo Souza 2023-01-18 13:55:04 -03:00 committed by GitHub
parent 2c78078814
commit 525c5e237a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 177 additions and 17 deletions

View File

@ -73,7 +73,7 @@ fn test_types() {
assert json.decode[StructType[int]]('{"val": 0}')!.val == 0
assert json.decode[StructType[int]]('{"val": 1}')!.val == 1
assert json.decode[StructType[int]]('{"val": 2}')!.val == 2
assert json.decode[StructType[int]]('{"val": "true"}')!.val == 1
assert json.decode[StructType[int]]('{"val": "true"}')!.val == 0
assert json.decode[StructType[int]]('{"val": "false"}')!.val == 0
assert json.decode[StructType[int]]('{"val": true}')!.val == 1
assert json.decode[StructType[int]]('{"val": false}')!.val == 0

View File

@ -108,6 +108,42 @@ pub fn encode_pretty[T](typed_data T) string {
return raw_decoded.prettify_json_str()
}
// i8 - TODO
pub fn (f Any) i8() i8 {
match f {
i8 {
return f
}
i16, int, i64, u8, u16, u32, u64, f32, f64, bool {
return i8(f)
}
string {
return f.i8()
}
else {
return 0
}
}
}
// i16 - TODO
pub fn (f Any) i16() i16 {
match f {
i16 {
return f
}
i8, int, i64, u8, u16, u32, u64, f32, f64, bool {
return i16(f)
}
string {
return f.i16()
}
else {
return 0
}
}
}
// int uses `Any` as an integer.
pub fn (f Any) int() int {
match f {
@ -118,9 +154,6 @@ pub fn (f Any) int() int {
return int(f)
}
string {
if f == 'false' || f == 'true' {
return int(f.bool())
}
return f.int()
}
else {
@ -139,9 +172,6 @@ pub fn (f Any) i64() i64 {
return i64(f)
}
string {
if f == 'false' || f == 'true' {
return i64(f.bool())
}
return f.i64()
}
else {
@ -160,9 +190,6 @@ pub fn (f Any) u64() u64 {
return u64(f)
}
string {
if f == 'false' || f == 'true' {
return u64(f.bool())
}
return f.u64()
}
else {
@ -181,9 +208,6 @@ pub fn (f Any) f32() f32 {
return f32(f)
}
string {
if f == 'false' || f == 'true' {
return f32(f.bool())
}
return f.f32()
}
else {
@ -202,9 +226,6 @@ pub fn (f Any) f64() f64 {
return f64(f)
}
string {
if f == 'false' || f == 'true' {
return f64(f.bool())
}
return f.f64()
}
else {
@ -220,8 +241,14 @@ pub fn (f Any) bool() bool {
return f
}
string {
if f == 'false' {
return false
}
if f == 'true' {
return true
}
if f.len > 0 {
return f != '0' && f != '0.0' && f != 'false'
return f != '0' && f != '0.0'
} else {
return false
}
@ -309,3 +336,59 @@ pub fn (f Any) to_time() !time.Time {
}
}
}
fn map_from[T](t T) map[string]Any {
mut m := map[string]Any{}
$if T is $Struct {
$for field in T.fields {
value := t.$(field.name)
$if field.is_array {
mut arr := []Any{}
for variable in value {
arr << Any(variable)
}
m[field.name] = arr
arr.clear()
} $else $if field.is_struct {
m[field.name] = map_from(value)
} $else $if field.is_map {
// TODO
} $else $if field.is_alias {
// TODO
} $else $if field.is_option {
// TODO
} $else {
// TODO improve memory usage when convert
$if field.typ is string {
m[field.name] = value.str()
} $else $if field.typ is bool {
m[field.name] = t.$(field.name).str().bool()
} $else $if field.typ is i8 {
m[field.name] = t.$(field.name).str().i8()
} $else $if field.typ is i16 {
m[field.name] = t.$(field.name).str().i16()
} $else $if field.typ is int {
m[field.name] = t.$(field.name).str().int()
} $else $if field.typ is i64 {
m[field.name] = t.$(field.name).str().i64()
} $else $if field.typ is f32 {
m[field.name] = t.$(field.name).str().f32()
} $else $if field.typ is f64 {
m[field.name] = t.$(field.name).str().f64()
} $else $if field.typ is u8 {
m[field.name] = t.$(field.name).str().u8()
} $else $if field.typ is u16 {
m[field.name] = t.$(field.name).str().u16()
} $else $if field.typ is u32 {
m[field.name] = t.$(field.name).str().u32()
} $else $if field.typ is u64 {
m[field.name] = t.$(field.name).str().u64()
} $else {
// return error("The type of `${field.name}` can't be decoded. Please open an issue at https://github.com/vlang/v/issues/new/choose")
}
}
}
}
return m
}

View File

@ -44,3 +44,80 @@ fn test_character_unescape() {
assert lines['quotes'] or { 0 }.str() == '"quotes"'
assert lines['slash'] or { 0 }.str() == '/dev/null'
}
struct StructType[T] {
mut:
val T
}
fn test_struct_with_bool_to_map() {
array_of_struct := [StructType[bool]{
val: true
}, StructType[bool]{
val: false
}]
mut array_of_map := []json.Any{}
for variable in array_of_struct {
array_of_map << json.map_from(variable)
}
assert array_of_map.str() == '[{"val":true},{"val":false}]'
}
fn test_struct_with_string_to_map() {
array_of_struct := [StructType[string]{
val: 'true'
}, StructType[string]{
val: 'false'
}]
mut array_of_map := []json.Any{}
for variable in array_of_struct {
array_of_map << json.map_from(variable)
}
assert array_of_map.str() == '[{"val":"true"},{"val":"false"}]'
}
fn test_struct_with_array_to_map() {
array_of_struct := [StructType[[]bool]{
val: [false, true]
}, StructType[[]bool]{
val: [true, false]
}]
mut array_of_map := []json.Any{}
for variable in array_of_struct {
array_of_map << json.map_from(variable)
}
assert array_of_map.str() == '[{"val":[false,true]},{"val":[true,false]}]'
}
fn test_struct_with_number_to_map() {
assert json.map_from(StructType[string]{'3'}).str() == '{"val":"3"}'
assert json.map_from(StructType[bool]{true}).str() == '{"val":true}'
assert json.map_from(StructType[i8]{3}).str() == '{"val":3}'
assert json.map_from(StructType[i16]{3}).str() == '{"val":3}'
assert json.map_from(StructType[int]{3}).str() == '{"val":3}'
assert json.map_from(StructType[i64]{3}).str() == '{"val":3}'
assert json.map_from(StructType[i8]{-3}).str() == '{"val":-3}'
assert json.map_from(StructType[i16]{i16(-3)}).str() == '{"val":-3}'
assert json.map_from(StructType[int]{-3}).str() == '{"val":-3}'
assert json.map_from(StructType[i64]{-3}).str() == '{"val":-3}'
assert json.map_from(StructType[f32]{3.0}).str() == '{"val":3.0}'
assert json.map_from(StructType[f64]{3.0}).str() == '{"val":3.0}'
assert json.map_from(StructType[u8]{3}).str() == '{"val":3}'
assert json.map_from(StructType[u16]{3}).str() == '{"val":3}'
assert json.map_from(StructType[u32]{3}).str() == '{"val":3}'
assert json.map_from(StructType[u64]{3}).str() == '{"val":3}'
}
fn test_struct_with_struct_to_map() {
assert json.map_from(StructType[StructType[string]]{StructType[string]{'3'}}).str() == '{"val":{"val":"3"}}'
assert json.map_from(StructType[StructType[int]]{StructType[int]{3}}).str() == '{"val":{"val":3}}'
}