toml: add conversion of ast inf and nan to Any (#12567)

pull/12580/head
Larpon 2021-11-25 11:33:54 +01:00 committed by GitHub
parent fb3a793a27
commit 9a2c563735
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 12 deletions

View File

@ -1,4 +1,5 @@
import toml import toml
import strconv
const toml_text = ' const toml_text = '
modules = [ "ui", "toml" ] modules = [ "ui", "toml" ]
@ -23,7 +24,10 @@ id = 1
id = 2 id = 2
[values] [values]
nan = nan
inf = inf
test = 2 test = 2
minus-inf = -inf
[[themes]] [[themes]]
name = "Ice" name = "Ice"
@ -45,6 +49,7 @@ fn test_value_query_in_array() {
assert value == 'toml' assert value == 'toml'
value = toml_doc.value('errors[11]').default_to('<none>').string() value = toml_doc.value('errors[11]').default_to('<none>').string()
assert value == '<none>' assert value == '<none>'
value = toml_doc.value('themes[2].colors[0]').string() value = toml_doc.value('themes[2].colors[0]').string()
assert value == 'blue' assert value == 'blue'
} }
@ -75,3 +80,15 @@ fn test_any_value_query() {
any = any.value('test') any = any.value('test')
assert any.int() == 2 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
}

View File

@ -12,7 +12,7 @@ type DocOrAny = toml.Any | toml.Doc
pub fn json(doa DocOrAny) string { pub fn json(doa DocOrAny) string {
match doa { match doa {
toml.Doc { 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 { toml.Any {
return any_to_json(doa) return any_to_json(doa)

View File

@ -167,7 +167,7 @@ fn parse_array_key(key string) (string, int) {
// to_any converts the `Doc` to toml.Any type. // to_any converts the `Doc` to toml.Any type.
pub fn (d Doc) to_any() Any { 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. // 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 { if key.len <= 1 {
return d.ast_to_any(ast_value) return ast_to_any(ast_value)
} }
match ast_value { match ast_value {
map[string]ast.Value, []ast.Value { map[string]ast.Value, []ast.Value {
return d.value_(ast_value, key[1..]) return d.value_(ast_value, key[1..])
} }
else { else {
return d.ast_to_any(value) return ast_to_any(value)
} }
} }
} }
// ast_to_any converts `from` ast.Value to toml.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 { match value {
ast.Date { ast.Date {
return Any(Date{value.text}) return Any(Date{value.text})
@ -228,11 +228,22 @@ pub fn (d Doc) ast_to_any(value ast.Value) Any {
return Any(value.text) return Any(value.text)
} }
ast.Number { ast.Number {
// if value.text.contains('inf') || value.text.contains('nan') { val_text := value.text
// return Any() // TODO if val_text == 'inf' || val_text == '+inf' || val_text == '-inf' {
//} // NOTE values taken from strconv
if !value.text.starts_with('0x') if !val_text.starts_with('-') {
&& (value.text.contains('.') || value.text.to_lower().contains('e')) { // 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.f64())
} }
return Any(value.i64()) 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) m := (value as map[string]ast.Value)
mut am := map[string]Any{} mut am := map[string]Any{}
for k, v in m { for k, v in m {
am[k] = d.ast_to_any(v) am[k] = ast_to_any(v)
} }
return am return am
// return d.get_map_value(m, key_split[1..].join('.')) // 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) a := (value as []ast.Value)
mut aa := []Any{} mut aa := []Any{}
for val in a { for val in a {
aa << d.ast_to_any(val) aa << ast_to_any(val)
} }
return aa return aa
} }