package conformist
Install
Dune Dependency
Authors
Maintainers
Sources
md5=462215fd0a1615b1f3686da1c80d2351
sha512=ad1cbe53293e4269d9be47edc5f3e1303b5707dd59715e29d0928b348661aab2d75977e88b4ec4841f2ec5931cd018d40b781911e503dcb5d3a5e3b0d3994aeb
Description
Conformist allows you to define schemas to decode, validate and sanitize input data declaratively.
It comes with runtime types for primitive OCaml types such as int
, string
, bool
and float
but also Ptime.t
, option
and custom types.
Re-use business rules in validators and run it on the client side with js_of_ocaml.
Arbitrary meta data can be stored in schemas which is useful to build functionality on top of conformist.
Published: 03 May 2021
README
README.md
Conformist
Schema definition and validation with support for decoding to bridge the gap between runtime types and static types.
Explore the docs »
Table of Contents
About
Conformist allows you to define schemas to decode, validate and sanitize input data declaratively. It comes with runtime types for primitive OCaml types such as int
, string
, bool
, float
and Ptime.t
, option
and custom types. Re-use business rules in validators and run it on the client side with js_of_ocaml. Arbitrary meta data can be stored in schemas which is useful to build functionality on top of conformist.
Typical use cases are enforcing invariants of models or user input sanitization.
In essence, conformist helps you to keep your runtime types/contracts in sync with your static types.
Installation
opam install conformist
In your dune
file:
(executable
(name app)
(libraries
...
conformist))
Usage
Let's look at an example.
type occupation =
| Mathematician
| Engineer
type user =
{ occupation : occupation
; email : string
; birthday : Ptime.t
; nr_of_siblings : int
; comment : string option
; favorite_shows : string list
; wants_premium : bool
}
let user
occupation
email
birthday
nr_of_siblings
comment
favorite_shows
wants_premium
=
{ occupation
; email
; birthday
; nr_of_siblings
; comment
; favorite_shows
; wants_premium
}
;;
let occupation_decoder = function
| [ "mathematician" ] -> Ok Mathematician
| [ "engineer" ] -> Ok Engineer
| _ -> Error "Unknown occupation provided"
;;
let occupation_encoder = function
| Mathematician -> [ "mathematician" ]
| Engineer -> [ "engineer" ]
;;
let user_schema =
Conformist.(
make
[ custom occupation_decoder occupation_encoder "occupation" ~meta:()
; string "email"
; datetime "birthday"
; int ~default:0 "nr_of_siblings"
; optional (string "comment")
; list (string "favorite_shows")
; bool "wants_premium"
]
user)
;;
let input =
[ "occupation", [ "engineer" ]
; "email", [ "test@example.com" ]
; "birthday", [ "2020-12-01T00:00:00.00Z" ]
; "nr_of_siblings", [ "3" ]
; "comment", [ "hello" ]
; "wants_premium", [ "true" ]
]
;;
let user = Conformist.decode Schema.user_schema input
let validation_errors = Conformist.validate Schema.user_schema input
Try to delete/swap some lines of the list of fields, to change the constructor or the user type. The compiler forces you to keep these three things in sync.
Decoding doesn't validate the data, it just makes sure that the types are correct and translates strings to the correct static types.
Note that if decoding of a field fails, validation fails as well. Before a field is validated, it gets decoded.
Documentation
The documentation for the latest released version can be found here.
License
Copyright (c) 2020 Oxidizing Systems
Distributed under the MIT License. See LICENSE
for more information.
Acknowledgements
The implementation of this project was inspired by archi and re-web.