opt ... t and req ... (option t) don't have the same behaviour regarding null
type anob = { a : string; b : string option }
let aopt_enc =
let open Data_encoding in
conv
(fun { a; b } -> (a, b))
(fun (a, b) -> { a; b })
(obj2 (req "a" string) (opt "b" string))
let aro_enc =
let open Data_encoding in
conv
(fun { a; b } -> (a, b))
(fun (a, b) -> { a; b })
(obj2 (req "a" string) (req "b" (option string)))
let anob = {| { "a" : "blah" } |}
let anull = {| { "a" : "blah", "b" : null } |}
let () =
let open Data_encoding in
(* Parsing no b field with opt *)
Json.from_string anob |> Result.get_ok |> Json.destruct aopt_enc |> fun a ->
Format.eprintf "%s@." a.a;
(* Parsing no b field with req option > Commented since it fails *)
(* Json.from_string anob |> Result.get_ok |> Json.destruct aro_enc |> fun a ->
* Format.eprintf "%s@." a.a *)
(* Parsing null b field with opt > Commented since it fails *)
(* Json.from_string anull |> Result.get_ok |> Json.destruct aopt_enc |> fun a ->
* Format.eprintf "%s@." a.a *)
(* Parsing null b field with req option *)
Json.from_string anull |> Result.get_ok |> Json.destruct aro_enc |> fun a ->
Format.eprintf "%s@." a.a
This quick code shows that (opt ... t)
and (req ... (option t))
don't have the same behaviour:
-
(opt ... t)
will succeed when the data is not here but fail when its value isnull
-
(req ... (option t))
will fail when the data is not here but succeed when its value isnull
I couldn't find anywhere informations regarding this and the error message was actually a bit hard to decypher but I think it would be nice to just write somewhere (in the doc comment of opt for example) that it doesn't work with null
and that (req ... (option t))
should be used.