gleam-lang / json

🐑 Work with JSON in Gleam!

Home Page:https://hexdocs.pm/gleam_json/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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) })
          },
        ]),
      ),
    )
}