toml: add Any.default_to() method (#12506)

pull/12518/head
Larpon 2021-11-19 09:26:45 +01:00 committed by GitHub
parent b367ed9ba3
commit 76cf11e6b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 16 deletions

View File

@ -149,18 +149,26 @@ pub fn (a Any) datetime() DateTime {
} }
} }
// default_to returns `value` if `a Any` is `Null`.
// This can be used to set default values when retrieving
// values. E.g.: `toml_doc.value('wrong.key').default_to(123).int()`
pub fn (a Any) default_to(value Any) Any {
match a {
Null { return value }
else { return a }
}
}
// value queries a value from the map. // value queries a value from the map.
// `key` should be in "dotted" form (`a.b.c`). // `key` should be in "dotted" form (`a.b.c`).
// `key` supports quoted keys like `a."b.c"`. // `key` supports quoted keys like `a."b.c"`.
pub fn (m map[string]Any) value(key string) ?Any { pub fn (m map[string]Any) value(key string) Any {
key_split := parse_dotted_key(key) ? key_split := parse_dotted_key(key) or { return Any(Null{}) }
return m.value_(key_split) return m.value_(key_split)
} }
fn (m map[string]Any) value_(key []string) ?Any { fn (m map[string]Any) value_(key []string) Any {
value := m[key[0]] or { value := m[key[0]] or { return Any(Null{}) }
return error(@MOD + '.' + @STRUCT + '.' + @FN + ' key "${key[0]}" does not exist')
}
// `match` isn't currently very suitable for these types of sum type constructs... // `match` isn't currently very suitable for these types of sum type constructs...
if value is map[string]Any { if value is map[string]Any {
if key.len <= 1 { if key.len <= 1 {

View File

@ -0,0 +1,9 @@
import toml
fn test_default_to() {
default_value := 4321
mut toml_txt := 'var = 1234'
toml_doc := toml.parse(toml_txt) or { panic(err) }
value := toml_doc.value('tar').default_to(default_value).int()
assert value == default_value
}

View File

@ -61,31 +61,31 @@ fn test_tables() {
mut m := toml_doc.value('tbl') as map[string]toml.Any mut m := toml_doc.value('tbl') as map[string]toml.Any
value = m.value('a.b.c.d.e') or { panic(err) } value = m.value('a.b.c.d.e')
assert value.int() == 1 assert value.int() == 1
value = m.value('x.a.b.c.d.e') or { panic(err) } value = m.value('x.a.b.c.d.e')
assert value.int() == 1 assert value.int() == 1
arr := toml_doc.value('arr') as []toml.Any arr := toml_doc.value('arr') as []toml.Any
for i := 0; i < arr.len; i++ { for i := 0; i < arr.len; i++ {
entry := (arr[i] as map[string]toml.Any) entry := (arr[i] as map[string]toml.Any)
value = entry.value('t.a.b') or { panic(err) } value = entry.value('t.a.b')
assert value.int() == i + 1 assert value.int() == i + 1
value = entry.value('T.a.b') or { panic(err) } value = entry.value('T.a.b')
assert value.int() == i + 1 assert value.int() == i + 1
} }
arr0 := arr[0] as map[string]toml.Any arr0 := arr[0] as map[string]toml.Any
value = arr0.value('t.a.b') or { panic(err) } value = arr0.value('t.a.b')
assert value.int() == 1 assert value.int() == 1
value = arr0.value('T.a.b') or { panic(err) } value = arr0.value('T.a.b')
assert value.int() == 1 assert value.int() == 1
arr1 := arr[1] as map[string]toml.Any arr1 := arr[1] as map[string]toml.Any
value = arr1.value('t.a.b') or { panic(err) } value = arr1.value('t.a.b')
assert value.int() == 2 assert value.int() == 2
value = arr1.value('T.a.b') or { panic(err) } value = arr1.value('T.a.b')
assert value.int() == 2 assert value.int() == 2
} }

View File

@ -25,7 +25,7 @@ fn test_toml_with_bom() {
assert title as string == 'TOML Example' assert title as string == 'TOML Example'
owner := toml_doc.value('owner') as map[string]toml.Any owner := toml_doc.value('owner') as map[string]toml.Any
any_name := owner.value('name') or { panic(err) } any_name := owner.value('name')
assert any_name.string() == 'Tom Preston-Werner' assert any_name.string() == 'Tom Preston-Werner'
database := toml_doc.value('database') as map[string]toml.Any database := toml_doc.value('database') as map[string]toml.Any

View File

@ -10,7 +10,7 @@ fn test_toml_known_memory_corruption() {
toml_doc := toml.parse(toml_text) or { panic(err) } toml_doc := toml.parse(toml_text) or { panic(err) }
owner := toml_doc.value('owner') as map[string]toml.Any owner := toml_doc.value('owner') as map[string]toml.Any
any_name := owner.value('name') or { panic(err) } any_name := owner.value('name')
// This assert code path will cause the corruption. // This assert code path will cause the corruption.
assert any_name.string() == 'Tom Preston-Werner' assert any_name.string() == 'Tom Preston-Werner'