diff --git a/common/mltools/JSON.ml b/common/mltools/JSON.ml index 1a88f8b1f..a51037ab4 100644 --- a/common/mltools/JSON.ml +++ b/common/mltools/JSON.ml @@ -23,6 +23,7 @@ and json_t = | String of string | Int of int | Int64 of int64 + | Float of float | Bool of bool | List of json_t list | Dict of field list @@ -110,6 +111,11 @@ and output_field ~indent ~fmt = function | Int i -> string_of_int i | Bool b -> if b then "true" else "false" | Int64 i -> Int64.to_string i + (* The JSON standard permits either "1" or "1.0" but not "1.". + * OCaml string_of_float will generate "1.", but the %g formatter + * will only generate the valid JSON values. + *) + | Float f -> Printf.sprintf "%g" f | List l -> output_list ~indent:(indent + 1) ~fmt l | Dict d -> output_dict ~indent:(indent + 1) ~fmt d diff --git a/common/mltools/JSON.mli b/common/mltools/JSON.mli index 5b487af8e..06a777c20 100644 --- a/common/mltools/JSON.mli +++ b/common/mltools/JSON.mli @@ -23,6 +23,7 @@ and json_t = (** JSON value. *) | String of string (** string value, eg. ["string"] *) | Int of int (** int value, eg. [99] *) | Int64 of int64 (** int64 value, eg. [99] *) + | Float of float (** floating point value, eg. [9.9] *) | Bool of bool (** boolean value, [true] or [false] *) | List of json_t list (** array value, eg. [[1,2,3]] *) | Dict of field list (** object, eg. [{ "a": 1, "b": "c" }] *) diff --git a/common/mltools/JSON_tests.ml b/common/mltools/JSON_tests.ml index 55a474474..2f3998e6e 100644 --- a/common/mltools/JSON_tests.ml +++ b/common/mltools/JSON_tests.ml @@ -71,6 +71,25 @@ let test_int ctx = }" (JSON.string_of_doc ~fmt:JSON.Indented doc) +let test_float ctx = + let doc = [ "test_zero", JSON.Float 0.; + "test_one", JSON.Float 1.; + "test_frac", JSON.Float 1.5; + "test_neg_frac", JSON.Float (-1.5); + "test_exp", JSON.Float 1e100 ] in + assert_equal_string + "{ \"test_zero\": 0, \"test_one\": 1, \"test_frac\": 1.5, \"test_neg_frac\": -1.5, \"test_exp\": 1e+100 }" + (JSON.string_of_doc doc); + assert_equal_string + "{ + \"test_zero\": 0, + \"test_one\": 1, + \"test_frac\": 1.5, + \"test_neg_frac\": -1.5, + \"test_exp\": 1e+100 +}" + (JSON.string_of_doc ~fmt:JSON.Indented doc) + let test_list ctx = let doc = [ "item", JSON.List [ JSON.String "foo"; JSON.Int 10; JSON.Bool true ] ] in assert_equal_string @@ -227,6 +246,7 @@ let suite = "basic.string" >:: test_string; "basic.bool" >:: test_bool; "basic.int" >:: test_int; + "basic.float" >:: test_float; "basic.list" >:: test_list; "basic.nested_dict" >:: test_nested_dict; "basic.nested_nested dict" >:: test_nested_nested_dict;