From 9a2c563735b99600af9e0d3042c61c4cc8e31fa0 Mon Sep 17 00:00:00 2001 From: Larpon Date: Thu, 25 Nov 2021 11:33:54 +0100 Subject: [PATCH] toml: add conversion of ast inf and nan to Any (#12567) --- vlib/toml/tests/value_query_test.v | 17 +++++++++++++++ vlib/toml/to/to.v | 2 +- vlib/toml/toml.v | 33 ++++++++++++++++++++---------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/vlib/toml/tests/value_query_test.v b/vlib/toml/tests/value_query_test.v index ef084325e6..c9f1aeaeb3 100644 --- a/vlib/toml/tests/value_query_test.v +++ b/vlib/toml/tests/value_query_test.v @@ -1,4 +1,5 @@ import toml +import strconv const toml_text = ' modules = [ "ui", "toml" ] @@ -23,7 +24,10 @@ id = 1 id = 2 [values] +nan = nan +inf = inf test = 2 +minus-inf = -inf [[themes]] name = "Ice" @@ -45,6 +49,7 @@ fn test_value_query_in_array() { assert value == 'toml' value = toml_doc.value('errors[11]').default_to('').string() assert value == '' + value = toml_doc.value('themes[2].colors[0]').string() assert value == 'blue' } @@ -75,3 +80,15 @@ fn test_any_value_query() { any = any.value('test') assert any.int() == 2 } + +fn test_inf_and_nan_query() { + toml_doc := toml.parse(toml_text) or { panic(err) } + + value := toml_doc.value('values.nan').string() + assert value == 'nan' + + mut value_u64 := toml_doc.value('values.inf').u64() + assert value_u64 == strconv.double_plus_infinity + value_u64 = toml_doc.value('values.minus-inf').u64() + assert value_u64 == strconv.double_minus_infinity +} diff --git a/vlib/toml/to/to.v b/vlib/toml/to/to.v index 469dfd1c73..502cfdfa98 100644 --- a/vlib/toml/to/to.v +++ b/vlib/toml/to/to.v @@ -12,7 +12,7 @@ type DocOrAny = toml.Any | toml.Doc pub fn json(doa DocOrAny) string { match doa { toml.Doc { - return any_to_json(doa.ast_to_any(doa.ast.table)) + return any_to_json(toml.ast_to_any(doa.ast.table)) } toml.Any { return any_to_json(doa) diff --git a/vlib/toml/toml.v b/vlib/toml/toml.v index 3bbce08495..5cc098ee87 100644 --- a/vlib/toml/toml.v +++ b/vlib/toml/toml.v @@ -167,7 +167,7 @@ fn parse_array_key(key string) (string, int) { // to_any converts the `Doc` to toml.Any type. pub fn (d Doc) to_any() Any { - return d.ast_to_any(d.ast.table) + return ast_to_any(d.ast.table) } // value queries a value from the TOML document. @@ -200,20 +200,20 @@ fn (d Doc) value_(value ast.Value, key []string) Any { } if key.len <= 1 { - return d.ast_to_any(ast_value) + return ast_to_any(ast_value) } match ast_value { map[string]ast.Value, []ast.Value { return d.value_(ast_value, key[1..]) } else { - return d.ast_to_any(value) + return ast_to_any(value) } } } // ast_to_any converts `from` ast.Value to toml.Any value. -pub fn (d Doc) ast_to_any(value ast.Value) Any { +pub fn ast_to_any(value ast.Value) Any { match value { ast.Date { return Any(Date{value.text}) @@ -228,11 +228,22 @@ pub fn (d Doc) ast_to_any(value ast.Value) Any { return Any(value.text) } ast.Number { - // if value.text.contains('inf') || value.text.contains('nan') { - // return Any() // TODO - //} - if !value.text.starts_with('0x') - && (value.text.contains('.') || value.text.to_lower().contains('e')) { + val_text := value.text + if val_text == 'inf' || val_text == '+inf' || val_text == '-inf' { + // NOTE values taken from strconv + if !val_text.starts_with('-') { + // strconv.double_plus_infinity + return Any(u64(0x7FF0000000000000)) + } else { + // strconv.double_minus_infinity + return Any(u64(0xFFF0000000000000)) + } + } + if val_text == 'nan' || val_text == '+nan' || val_text == '-nan' { + return Any('nan') + } + if !val_text.starts_with('0x') + && (val_text.contains('.') || val_text.to_lower().contains('e')) { return Any(value.f64()) } return Any(value.i64()) @@ -248,7 +259,7 @@ pub fn (d Doc) ast_to_any(value ast.Value) Any { m := (value as map[string]ast.Value) mut am := map[string]Any{} for k, v in m { - am[k] = d.ast_to_any(v) + am[k] = ast_to_any(v) } return am // return d.get_map_value(m, key_split[1..].join('.')) @@ -257,7 +268,7 @@ pub fn (d Doc) ast_to_any(value ast.Value) Any { a := (value as []ast.Value) mut aa := []Any{} for val in a { - aa << d.ast_to_any(val) + aa << ast_to_any(val) } return aa }