[ANN] dream-html 3.7.0
Happy to announce the addition of a helper module for typed form decoding functionality. See the docs here: Form (dream-html.Dream_html.Form)
An example:
type user = { name : string; age : int option }
open Dream_html.Form
let user_form =
let+ name = required string "name"
and+ age = optional int "age" in
{ name; age }
let dream_form = ["age", "42"; "name", "Bob"]
let user_result = validate user_form dream_form
(* => Ok { name = "Bob"; age = Some 42 } *)
let error_result = validate user_form ["age", "none"]
(* => Error [("age", "error.expected.int"); ("name", "error.required")] *)
Astute readers may observe that this provides some convenience functionality beyond what Dream itself offers; to validate the above form and get a complete set of field validation errors using only Dream you would do something like:
let user_result = match dream_form with
| ["age", age; "name", name] ->
(match int_of_string age with
| age -> Ok { name; age = Some age }
| exception Failure _ -> Error ["age", "error.expected.int"])
| ["name", name] -> Ok { name; age = None }
| ["age", age] ->
(match int_of_string age with
| age -> Error ["name", "error.required"]
| exception Failure _ -> Error ["age", "error.expected.int"; "name", "error.required"])
| _ -> Error ["name", "error.required"]
And this is a form with only two fields. You can imagine how convoluted the logic would be for more complex forms. Of course, you might just decide to use List.assoc_opt
and build up the validation errors, but even that can get tricky. So if you are making heavy use of HTML forms, a helper module that takes care of all these validation details can be very useful. Enjoy!