toml: add `pub fn (d Doc) value_opt(key string) ?Any {` and some tests for toml.parse_dotted_key/1
parent
a971b9a99a
commit
4894f61998
|
@ -281,24 +281,35 @@ pub fn (a []Any) to_toml() string {
|
||||||
// quoted keys are supported as `a."b.c"` or `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]`.
|
// Arrays can be queried with `a[0].b[1].[2]`.
|
||||||
pub fn (a Any) value(key string) Any {
|
pub fn (a Any) value(key string) Any {
|
||||||
key_split := parse_dotted_key(key) or { return Any(Null{}) }
|
key_split := parse_dotted_key(key) or { return null }
|
||||||
return a.value_(a, key_split)
|
return a.value_(a, key_split)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (a Any) value_opt(key string) ?Any {
|
||||||
|
key_split := parse_dotted_key(key) or { return error('invalid dotted key') }
|
||||||
|
x := a.value_(a, key_split)
|
||||||
|
if x is Null {
|
||||||
|
return error('no value for key')
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
// value_ returns the `Any` value found at `key`.
|
// value_ returns the `Any` value found at `key`.
|
||||||
fn (a Any) value_(value Any, key []string) Any {
|
fn (a Any) value_(value Any, key []string) Any {
|
||||||
assert key.len > 0
|
if key.len == 0 {
|
||||||
mut any_value := Any(Null{})
|
return null
|
||||||
|
}
|
||||||
|
mut any_value := null
|
||||||
k, index := parse_array_key(key[0])
|
k, index := parse_array_key(key[0])
|
||||||
if k == '' {
|
if k == '' {
|
||||||
arr := value as []Any
|
arr := value as []Any
|
||||||
any_value = arr[index] or { return Any(Null{}) }
|
any_value = arr[index] or { return null }
|
||||||
}
|
}
|
||||||
if value is map[string]Any {
|
if value is map[string]Any {
|
||||||
any_value = value[k] or { return Any(Null{}) }
|
any_value = value[k] or { return null }
|
||||||
if index > -1 {
|
if index > -1 {
|
||||||
arr := any_value as []Any
|
arr := any_value as []Any
|
||||||
any_value = arr[index] or { return Any(Null{}) }
|
any_value = arr[index] or { return null }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if key.len <= 1 {
|
if key.len <= 1 {
|
||||||
|
|
|
@ -2,11 +2,12 @@ import os
|
||||||
import toml
|
import toml
|
||||||
import toml.to
|
import toml.to
|
||||||
|
|
||||||
fn test_keys() {
|
fn path_by_extension(ext string) string {
|
||||||
toml_file :=
|
return os.join_path(os.dir(@VEXE), 'vlib/toml/tests/testdata/key_test.$ext')
|
||||||
os.real_path(os.join_path(os.dir(@FILE), 'testdata', os.file_name(@FILE).all_before_last('.'))) +
|
}
|
||||||
'.toml'
|
|
||||||
toml_doc := toml.parse_file(toml_file) or { panic(err) }
|
fn test_keys() ? {
|
||||||
|
toml_doc := toml.parse_file(path_by_extension('toml'))?
|
||||||
|
|
||||||
mut value := toml_doc.value('34-11')
|
mut value := toml_doc.value('34-11')
|
||||||
assert value.int() == 23
|
assert value.int() == 23
|
||||||
|
@ -18,10 +19,30 @@ fn test_keys() {
|
||||||
assert value.int() == 42
|
assert value.int() == 42
|
||||||
|
|
||||||
toml_json := to.json(toml_doc)
|
toml_json := to.json(toml_doc)
|
||||||
out_file :=
|
out_file_json := os.read_file(path_by_extension('out'))?
|
||||||
os.real_path(os.join_path(os.dir(@FILE), 'testdata', os.file_name(@FILE).all_before_last('.'))) +
|
|
||||||
'.out'
|
|
||||||
out_file_json := os.read_file(out_file) or { panic(err) }
|
|
||||||
println(toml_json)
|
println(toml_json)
|
||||||
assert toml_json == out_file_json
|
assert toml_json == out_file_json
|
||||||
|
//
|
||||||
|
if x := toml_doc.value_opt('unknown key') {
|
||||||
|
assert false
|
||||||
|
} else {
|
||||||
|
assert err.msg() == 'no value for key'
|
||||||
|
}
|
||||||
|
if x := toml_doc.value_opt("'a") {
|
||||||
|
assert false
|
||||||
|
} else {
|
||||||
|
assert err.msg() == 'invalid dotted key'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_parse_dotted_key() ? {
|
||||||
|
assert toml.parse_dotted_key('')? == []
|
||||||
|
assert toml.parse_dotted_key('abc')? == ['abc']
|
||||||
|
assert toml.parse_dotted_key('tube.test."test.test".h."i.j."."k"')? == ['tube', 'test',
|
||||||
|
'test.test', 'h', 'i.j.', 'k']
|
||||||
|
if x := toml.parse_dotted_key("'some unclosed string") {
|
||||||
|
assert false
|
||||||
|
} else {
|
||||||
|
assert err.msg().starts_with('parse_dotted_key: could not parse key, missing closing string delimiter')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,26 +201,39 @@ pub fn (d Doc) reflect<T>() T {
|
||||||
// quoted keys are supported as `a."b.c"` or `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]`.
|
// Arrays can be queried with `a[0].b[1].[2]`.
|
||||||
pub fn (d Doc) value(key string) Any {
|
pub fn (d Doc) value(key string) Any {
|
||||||
key_split := parse_dotted_key(key) or { return Any(Null{}) }
|
key_split := parse_dotted_key(key) or { return toml.null }
|
||||||
return d.value_(d.ast.table, key_split)
|
return d.value_(d.ast.table, key_split)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const null = Any(Null{})
|
||||||
|
|
||||||
|
pub fn (d Doc) value_opt(key string) ?Any {
|
||||||
|
key_split := parse_dotted_key(key) or { return error('invalid dotted key') }
|
||||||
|
x := d.value_(d.ast.table, key_split)
|
||||||
|
if x is Null {
|
||||||
|
return error('no value for key')
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
// value_ returns the value found at `key` in the map `values` as `Any` type.
|
// value_ returns the value found at `key` in the map `values` as `Any` type.
|
||||||
fn (d Doc) value_(value ast.Value, key []string) Any {
|
fn (d Doc) value_(value ast.Value, key []string) Any {
|
||||||
assert key.len > 0
|
if key.len == 0 {
|
||||||
|
return toml.null
|
||||||
|
}
|
||||||
mut ast_value := ast.Value(ast.Null{})
|
mut ast_value := ast.Value(ast.Null{})
|
||||||
k, index := parse_array_key(key[0])
|
k, index := parse_array_key(key[0])
|
||||||
|
|
||||||
if k == '' {
|
if k == '' {
|
||||||
a := value as []ast.Value
|
a := value as []ast.Value
|
||||||
ast_value = a[index] or { return Any(Null{}) }
|
ast_value = a[index] or { return toml.null }
|
||||||
}
|
}
|
||||||
|
|
||||||
if value is map[string]ast.Value {
|
if value is map[string]ast.Value {
|
||||||
ast_value = value[k] or { return Any(Null{}) }
|
ast_value = value[k] or { return toml.null }
|
||||||
if index > -1 {
|
if index > -1 {
|
||||||
a := ast_value as []ast.Value
|
a := ast_value as []ast.Value
|
||||||
ast_value = a[index] or { return Any(Null{}) }
|
ast_value = a[index] or { return toml.null }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,11 +311,11 @@ pub fn ast_to_any(value ast.Value) Any {
|
||||||
return aa
|
return aa
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Any(Null{})
|
return toml.null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Any(Null{})
|
return toml.null
|
||||||
// TODO decide this
|
// TODO decide this
|
||||||
// panic(@MOD + '.' + @STRUCT + '.' + @FN + ' can\'t convert "$value"')
|
// panic(@MOD + '.' + @STRUCT + '.' + @FN + ' can\'t convert "$value"')
|
||||||
// return Any('')
|
// return Any('')
|
||||||
|
|
Loading…
Reference in New Issue