mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
toml: add decoding for struct fields of type map[string]T (#19447)
This commit is contained in:
parent
bd9f42d14f
commit
12ee3fa86a
2 changed files with 73 additions and 10 deletions
|
@ -7,14 +7,15 @@ enum JobTitle {
|
|||
}
|
||||
|
||||
struct Pet {
|
||||
name string
|
||||
nicknames []string
|
||||
age u64
|
||||
income int
|
||||
height f32
|
||||
has_furr bool
|
||||
title JobTitle
|
||||
address Address
|
||||
name string
|
||||
nicknames []string
|
||||
age u64
|
||||
income int
|
||||
height f32
|
||||
has_furr bool
|
||||
title JobTitle
|
||||
address Address
|
||||
meal_frequency map[string]int
|
||||
// *¹ Currently it is only possible to decode a single nested struct generically.
|
||||
// As soon as we decode another nested struct (e.g. within this struct, like `contact` below)
|
||||
// or only one nested struct within another struct, it results in wrong values or errors.
|
||||
|
@ -58,7 +59,10 @@ struct Arrs {
|
|||
fn test_encode_and_decode() {
|
||||
// *¹
|
||||
// p := Pet{'Mr. Scratchy McEvilPaws', ['Freddy', 'Fred', 'Charles'], 8, -1, 0.8, true, .manager, Address{'1428 Elm Street', 'Springwood'}, Contact{'123-456-7890'}}
|
||||
p := Pet{'Mr. Scratchy McEvilPaws', ['Freddy', 'Fred', 'Charles'], 8, -1, 0.8, true, .manager, Address{'1428 Elm Street', 'Springwood'}}
|
||||
p := Pet{'Mr. Scratchy McEvilPaws', ['Freddy', 'Fred', 'Charles'], 8, -1, 0.8, true, .manager, Address{'1428 Elm Street', 'Springwood'}, {
|
||||
'bones': 2
|
||||
'kibble': 5
|
||||
}}
|
||||
s := 'name = "Mr. Scratchy McEvilPaws"
|
||||
nicknames = [
|
||||
"Freddy",
|
||||
|
@ -70,7 +74,8 @@ income = -1
|
|||
height = 0.8
|
||||
has_furr = true
|
||||
title = 2
|
||||
address = { street = "1428 Elm Street", city = "Springwood" }'
|
||||
address = { street = "1428 Elm Street", city = "Springwood" }
|
||||
meal_frequency = { bones = 2, kibble = 5 }'
|
||||
// contact = { phone = "123-456-7890" }' // *¹
|
||||
|
||||
assert toml.encode[Pet](p) == s
|
||||
|
|
|
@ -7,6 +7,7 @@ import toml.ast
|
|||
import toml.input
|
||||
import toml.scanner
|
||||
import toml.parser
|
||||
import maps
|
||||
|
||||
// Null is used in sumtype checks as a "default" value when nothing else is possible.
|
||||
pub struct Null {
|
||||
|
@ -70,6 +71,63 @@ fn decode_struct[T](doc Any, mut typ T) {
|
|||
'[]toml.Time' { typ.$(field.name) = arr.map(it.time()) }
|
||||
else {}
|
||||
}
|
||||
} $else $if field.is_map {
|
||||
mut mmap := value.as_map()
|
||||
match typeof(typ.$(field.name)).name {
|
||||
'map[string]string' {
|
||||
typ.$(field.name) = mmap.as_strings()
|
||||
}
|
||||
// Should be cleaned up to use the more modern lambda syntax
|
||||
// |k, v| k, v.int()
|
||||
// Unfortunately lambdas have issues with multiple return at the time of writing
|
||||
'map[string]int' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, int](mmap, fn (k string, v Any) (string, int) {
|
||||
return k, v.int()
|
||||
})
|
||||
}
|
||||
'map[string]i64' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, i64](mmap, fn (k string, v Any) (string, i64) {
|
||||
return k, v.i64()
|
||||
})
|
||||
}
|
||||
'map[string]u64' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, u64](mmap, fn (k string, v Any) (string, u64) {
|
||||
return k, v.u64()
|
||||
})
|
||||
}
|
||||
'map[string]f32' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, f32](mmap, fn (k string, v Any) (string, f32) {
|
||||
return k, v.f32()
|
||||
})
|
||||
}
|
||||
'map[string]f64' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, f64](mmap, fn (k string, v Any) (string, f64) {
|
||||
return k, v.f64()
|
||||
})
|
||||
}
|
||||
'map[string]bool' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, bool](mmap, fn (k string, v Any) (string, bool) {
|
||||
return k, v.bool()
|
||||
})
|
||||
}
|
||||
'map[string]toml.DateTime' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, DateTime](mmap,
|
||||
fn (k string, v Any) (string, DateTime) {
|
||||
return k, v.datetime()
|
||||
})
|
||||
}
|
||||
'map[string]toml.Date' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, Date](mmap, fn (k string, v Any) (string, Date) {
|
||||
return k, v.date()
|
||||
})
|
||||
}
|
||||
'map[string]toml.Time' {
|
||||
typ.$(field.name) = maps.to_map[string, Any, string, Time](mmap, fn (k string, v Any) (string, Time) {
|
||||
return k, v.time()
|
||||
})
|
||||
}
|
||||
else {}
|
||||
}
|
||||
} $else $if field.is_struct {
|
||||
mut s := typ.$(field.name)
|
||||
decode_struct(value, mut s)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue