From 76cf11e6b5113e3fce86955e2952c3a0a45cb203 Mon Sep 17 00:00:00 2001 From: Larpon Date: Fri, 19 Nov 2021 09:26:45 +0100 Subject: [PATCH] toml: add Any.default_to() method (#12506) --- vlib/toml/any.v | 20 +++++++++++++------ vlib/toml/tests/default_to_test.v | 9 +++++++++ vlib/toml/tests/table_test.v | 16 +++++++-------- vlib/toml/tests/toml_bom_test.v | 2 +- vlib/toml/tests/toml_memory_corruption_test.v | 2 +- 5 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 vlib/toml/tests/default_to_test.v diff --git a/vlib/toml/any.v b/vlib/toml/any.v index a43ba175fc..a3b2044a77 100644 --- a/vlib/toml/any.v +++ b/vlib/toml/any.v @@ -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. // `key` should be in "dotted" form (`a.b.c`). // `key` supports quoted keys like `a."b.c"`. -pub fn (m map[string]Any) value(key string) ?Any { - key_split := parse_dotted_key(key) ? +pub fn (m map[string]Any) value(key string) Any { + key_split := parse_dotted_key(key) or { return Any(Null{}) } return m.value_(key_split) } -fn (m map[string]Any) value_(key []string) ?Any { - value := m[key[0]] or { - return error(@MOD + '.' + @STRUCT + '.' + @FN + ' key "${key[0]}" does not exist') - } +fn (m map[string]Any) value_(key []string) Any { + value := m[key[0]] or { return Any(Null{}) } // `match` isn't currently very suitable for these types of sum type constructs... if value is map[string]Any { if key.len <= 1 { diff --git a/vlib/toml/tests/default_to_test.v b/vlib/toml/tests/default_to_test.v new file mode 100644 index 0000000000..2bf2283f43 --- /dev/null +++ b/vlib/toml/tests/default_to_test.v @@ -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 +} diff --git a/vlib/toml/tests/table_test.v b/vlib/toml/tests/table_test.v index c11b6962d4..43ade350b4 100644 --- a/vlib/toml/tests/table_test.v +++ b/vlib/toml/tests/table_test.v @@ -61,31 +61,31 @@ fn test_tables() { 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 - 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 arr := toml_doc.value('arr') as []toml.Any for i := 0; i < arr.len; i++ { 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 - value = entry.value('T.a.b') or { panic(err) } + value = entry.value('T.a.b') assert value.int() == i + 1 } 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 - value = arr0.value('T.a.b') or { panic(err) } + value = arr0.value('T.a.b') assert value.int() == 1 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 - value = arr1.value('T.a.b') or { panic(err) } + value = arr1.value('T.a.b') assert value.int() == 2 } diff --git a/vlib/toml/tests/toml_bom_test.v b/vlib/toml/tests/toml_bom_test.v index 8d76c7aec6..9111bd3bd3 100644 --- a/vlib/toml/tests/toml_bom_test.v +++ b/vlib/toml/tests/toml_bom_test.v @@ -25,7 +25,7 @@ fn test_toml_with_bom() { assert title as string == 'TOML Example' 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' database := toml_doc.value('database') as map[string]toml.Any diff --git a/vlib/toml/tests/toml_memory_corruption_test.v b/vlib/toml/tests/toml_memory_corruption_test.v index d5cde5b829..44f568d66f 100644 --- a/vlib/toml/tests/toml_memory_corruption_test.v +++ b/vlib/toml/tests/toml_memory_corruption_test.v @@ -10,7 +10,7 @@ fn test_toml_known_memory_corruption() { toml_doc := toml.parse(toml_text) or { panic(err) } 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. assert any_name.string() == 'Tom Preston-Werner'