Supporting floats from json represented like integers
rockerBOO opened this issue · comments
const x = {float: 1.0}
// x = {float: 1}
JSON.stringify(x)
// {"float": 1}
import gleam/dynamic.{dict, float, string}
import gleam/json
pub fn json_float_test() {
let json_string = "{\"float\": 1}"
let assert Ok(_) = json.decode(json_string, dict(string, float))
}
1) json_test.json_float_test: module 'json_test'
#{function => <<"json_float_test">>,line => 7,
message => <<"Assertion pattern match failed">>,
module => <<"json_test">>,
value =>
{error,
{unexpected_format,
[{decode_error,<<"Float">>,<<"Int">>,[<<"values">>]}]}},
gleam_error => let_assert}
location: json_test.json_float_test:7
stacktrace:
json_test.json_float_test
output:
And what would work if I made it manually and not use JSON.stringify
pub fn json_float_manually_test() {
let json_string = "{\"float\": 1.0}"
let assert Ok(_) = json.decode(json_string, dict(string, float))
}
Right now I am having to convert the float by adding 0.00000001 or some small value to it to force it to make it a float representation. Would it be possible to allow the 1 be able to be a float on the gleam side? Possibly there is some way to convert the int to a float in the process? Just that I want to pass it always as a float but the json string representation will convert it to an int if it's like 1.0.
Thank you.
I keep doing this, figuring it out after I make the post but here is how I fixed it... Take a any of float and then get an int and convert it to a float.
import gleam/dynamic.{any, dict, float, int, string}
import gleam/json
import gleam/result
import gleam/int
pub fn json_float_test() {
let json_string = "{\"float\": 1}"
let assert Ok(_) =
json.decode(
json_string,
dict(
string,
any([
float,
fn(x) {
int(x)
|> result.map(fn(i) { int.to_float(i) })
},
]),
),
)
}