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

toml: support arrays in value key query syntax (#12527)

This commit is contained in:
Larpon
2021-11-20 18:45:17 +01:00
committed by GitHub
parent 82010e729d
commit 4b9e8e243c
2 changed files with 67 additions and 15 deletions

View File

@@ -156,28 +156,48 @@ pub fn (d Doc) to_any() Any {
}
// value queries a value from the TOML document.
// `key` should be in "dotted" form (`a.b.c`).
// `key` supports quoted keys like `a."b.c"`.
// `key` supports a small query syntax scheme:
// Maps can be queried in "dotted" form e.g. `a.b.c`.
// quoted keys are supported as `a."b.c"` or `a.'b.c'`.
// Arrays can be queried with `a[0].b[1].[2]`.
pub fn (d Doc) value(key string) Any {
values := d.ast.table as map[string]ast.Value
key_split := parse_dotted_key(key) or { return Any(Null{}) }
return d.value_(values, key_split)
return d.value_(d.ast.table, key_split)
}
// value_ returns the value found at `key` in the map `values` as `Any` type.
fn (d Doc) value_(values map[string]ast.Value, key []string) Any {
value := values[key[0]] or {
return Any(Null{})
// TODO decide this
// panic(@MOD + '.' + @STRUCT + '.' + @FN + ' key "$key[0]" does not exist')
fn (d Doc) value_(value ast.Value, key []string) Any {
assert key.len > 0
mut ast_value := ast.Value(ast.Null{})
mut index := -1
mut k := key[0]
if k.contains('[') {
index = k.all_after('[').all_before(']').int()
if k.starts_with('[') {
k = '' // k.all_after(']')
} else {
k = k.all_before('[')
}
}
if k == '' {
a := value as []ast.Value
ast_value = a[index] or { return Any(Null{}) }
}
if value is map[string]ast.Value {
ast_value = value[k] or { return Any(Null{}) }
if index > -1 {
a := ast_value as []ast.Value
ast_value = a[index] or { return Any(Null{}) }
}
}
if key.len <= 1 {
return d.ast_to_any(ast_value)
}
// `match` isn't currently very suitable for these types of sum type constructs...
if value is map[string]ast.Value {
if key.len <= 1 {
return d.ast_to_any(value)
}
m := (value as map[string]ast.Value)
return d.value_(m, key[1..])
if ast_value is map[string]ast.Value || ast_value is []ast.Value {
return d.value_(ast_value, key[1..])
}
return d.ast_to_any(value)
}