Skip to content

Commit 9a2c563

Browse files
authored
toml: add conversion of ast inf and nan to Any (#12567)
1 parent fb3a793 commit 9a2c563

3 files changed

Lines changed: 40 additions & 12 deletions

File tree

vlib/toml/tests/value_query_test.v

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import toml
2+
import strconv
23

34
const toml_text = '
45
modules = [ "ui", "toml" ]
@@ -23,7 +24,10 @@ id = 1
2324
id = 2
2425
2526
[values]
27+
nan = nan
28+
inf = inf
2629
test = 2
30+
minus-inf = -inf
2731
2832
[[themes]]
2933
name = "Ice"
@@ -45,6 +49,7 @@ fn test_value_query_in_array() {
4549
assert value == 'toml'
4650
value = toml_doc.value('errors[11]').default_to('<none>').string()
4751
assert value == '<none>'
52+
4853
value = toml_doc.value('themes[2].colors[0]').string()
4954
assert value == 'blue'
5055
}
@@ -75,3 +80,15 @@ fn test_any_value_query() {
7580
any = any.value('test')
7681
assert any.int() == 2
7782
}
83+
84+
fn test_inf_and_nan_query() {
85+
toml_doc := toml.parse(toml_text) or { panic(err) }
86+
87+
value := toml_doc.value('values.nan').string()
88+
assert value == 'nan'
89+
90+
mut value_u64 := toml_doc.value('values.inf').u64()
91+
assert value_u64 == strconv.double_plus_infinity
92+
value_u64 = toml_doc.value('values.minus-inf').u64()
93+
assert value_u64 == strconv.double_minus_infinity
94+
}

vlib/toml/to/to.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type DocOrAny = toml.Any | toml.Doc
1212
pub fn json(doa DocOrAny) string {
1313
match doa {
1414
toml.Doc {
15-
return any_to_json(doa.ast_to_any(doa.ast.table))
15+
return any_to_json(toml.ast_to_any(doa.ast.table))
1616
}
1717
toml.Any {
1818
return any_to_json(doa)

vlib/toml/toml.v

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ fn parse_array_key(key string) (string, int) {
167167

168168
// to_any converts the `Doc` to toml.Any type.
169169
pub fn (d Doc) to_any() Any {
170-
return d.ast_to_any(d.ast.table)
170+
return ast_to_any(d.ast.table)
171171
}
172172

173173
// value queries a value from the TOML document.
@@ -200,20 +200,20 @@ fn (d Doc) value_(value ast.Value, key []string) Any {
200200
}
201201

202202
if key.len <= 1 {
203-
return d.ast_to_any(ast_value)
203+
return ast_to_any(ast_value)
204204
}
205205
match ast_value {
206206
map[string]ast.Value, []ast.Value {
207207
return d.value_(ast_value, key[1..])
208208
}
209209
else {
210-
return d.ast_to_any(value)
210+
return ast_to_any(value)
211211
}
212212
}
213213
}
214214

215215
// ast_to_any converts `from` ast.Value to toml.Any value.
216-
pub fn (d Doc) ast_to_any(value ast.Value) Any {
216+
pub fn ast_to_any(value ast.Value) Any {
217217
match value {
218218
ast.Date {
219219
return Any(Date{value.text})
@@ -228,11 +228,22 @@ pub fn (d Doc) ast_to_any(value ast.Value) Any {
228228
return Any(value.text)
229229
}
230230
ast.Number {
231-
// if value.text.contains('inf') || value.text.contains('nan') {
232-
// return Any() // TODO
233-
//}
234-
if !value.text.starts_with('0x')
235-
&& (value.text.contains('.') || value.text.to_lower().contains('e')) {
231+
val_text := value.text
232+
if val_text == 'inf' || val_text == '+inf' || val_text == '-inf' {
233+
// NOTE values taken from strconv
234+
if !val_text.starts_with('-') {
235+
// strconv.double_plus_infinity
236+
return Any(u64(0x7FF0000000000000))
237+
} else {
238+
// strconv.double_minus_infinity
239+
return Any(u64(0xFFF0000000000000))
240+
}
241+
}
242+
if val_text == 'nan' || val_text == '+nan' || val_text == '-nan' {
243+
return Any('nan')
244+
}
245+
if !val_text.starts_with('0x')
246+
&& (val_text.contains('.') || val_text.to_lower().contains('e')) {
236247
return Any(value.f64())
237248
}
238249
return Any(value.i64())
@@ -248,7 +259,7 @@ pub fn (d Doc) ast_to_any(value ast.Value) Any {
248259
m := (value as map[string]ast.Value)
249260
mut am := map[string]Any{}
250261
for k, v in m {
251-
am[k] = d.ast_to_any(v)
262+
am[k] = ast_to_any(v)
252263
}
253264
return am
254265
// 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 {
257268
a := (value as []ast.Value)
258269
mut aa := []Any{}
259270
for val in a {
260-
aa << d.ast_to_any(val)
271+
aa << ast_to_any(val)
261272
}
262273
return aa
263274
}

0 commit comments

Comments
 (0)