Skip to content

Commit

Permalink
toml: add decoding for struct fields of type map[string]T (#19447)
Browse files Browse the repository at this point in the history
  • Loading branch information
squidink7 committed Sep 26, 2023
1 parent bd9f42d commit 12ee3fa
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 10 deletions.
25 changes: 15 additions & 10 deletions vlib/toml/tests/encode_and_decode_test.v
Expand Up @@ -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.
Expand Down Expand Up @@ -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",
Expand All @@ -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
Expand Down
58 changes: 58 additions & 0 deletions vlib/toml/toml.v
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 12ee3fa

Please sign in to comment.