Key_value.Jsonm_validator
type t = Jsonm_object.t
Each simple validator checks that the element of type t
given as an argument respects the expected form.
val object_ : t -> (string * t) list Validate.t
object_ term
checks that term
is an object
and extract the object as a list of string * t
.
val list : t -> t list Validate.t
list term
checks that term
is a list
(and extract it).
val atom : t -> string Validate.t
atom term
checks that term
is an atom
, like atoms in SEXP
(and extract it as string
).
val string : t -> string Validate.t
string term
checks that term
is a string
(and extract it).
val boolean : t -> bool Validate.t
boolean term
checks that term
is a boolean
(and extract it).
val integer : t -> int Validate.t
list term
checks that term
is an integer
(and extract it).
val float : t -> float Validate.t
float term
checks that term
is a float
(and extract it).
val text : t -> string Validate.t
text term
checks that term
is not an objet
nor a list
(and extract the value as a string
).
val null : t -> unit Validate.t
Checks that a value is Null.
In addition to validating that an element of type t
has the expected form, a compound validator also applies an additional validation. For example string_and string_has_length 3
to validate that the element is a string and has a size of 3 (assuming the string_has_length x
function exists).
val object_and : ((string * t) list -> 'a Validate.t) -> t -> 'a Validate.t
object_and validator term
checks that term
is an object
and valid it using validator
.
val list_and : (t list -> 'a Validate.t) -> t -> 'a Validate.t
list_and validator term
checks that term
is a list
and valid it using validator
.
val list_of : (t -> 'a Validate.t) -> t -> 'a list Validate.t
list_of validator term
, ie: list_of int
checks if term
is a list that contains only values that satisfies the given validator.
val atom_and : (string -> 'a Validate.t) -> t -> 'a Validate.t
atom_and validator term
checks that term
is an atom
and valid it using validator
.
val string_and : (string -> 'a Validate.t) -> t -> 'a Validate.t
string_and validator term
checks that term
is a string
and valid it using validator
.
val boolean_and : (bool -> 'a Validate.t) -> t -> 'a Validate.t
boolean_and validator term
checks that term
is a boolean
and valid it using validator
.
val integer_and : (int -> 'a Validate.t) -> t -> 'a Validate.t
interger_and validator term
checks that term
is an integer
and valid it using validator
.
val float_and : (float -> 'a Validate.t) -> t -> 'a Validate.t
float_and validator term
checks that term
is a float
and valid it using validator
.
val text_and : (string -> 'a Validate.t) -> t -> 'a Validate.t
text_and validator term
checks that term
is a text
and valid it using validator
.
val null_and : (unit -> 'a Validate.t) -> t -> 'a Validate.t
null_and validator term
checks that term
is a Null
and valid it using validator
.
As object_
returns an associative list, you have to manipulate associative list functions over and over again to validate an object correctly, fortunately there are combinators to help with object validation.
val optional_field :
?case_sensitive:bool ->
(t -> 'a Validate.t) ->
string ->
t ->
'a option Validate.t
optional_field ?case_sensitive validator key term
try to reach the value at the key
position in term
, if the key is not associated the function will apply the validation and wrap it into an option, if the association is not present the function will returns None
. (case_sensitive
act on the key
and is false
by default)
val optional_field_or :
?case_sensitive:bool ->
default:'a ->
(t -> 'a Validate.t) ->
string ->
t ->
'a Validate.t
optional_field_or ?case_sensitive ~default validator key term
same of optional_field
but instead of wrapping the result into an option, it will apply default
if the association does not exists. (case_sensitive
act on the key
and is false
by default)
val required_field :
?case_sensitive:bool ->
(t -> 'a Validate.t) ->
string ->
t ->
'a Validate.t
required_field
is like optional_field
except that the association must exist, otherwise the check fails.
Let's imagine this type of data:
type user =
{ firstname : string
; lastname : string
; age : int
; activated : bool
; email : string option
}
let make_user firstname lastname age activated email =
{ firstname; lastname; age; activated; email }
;;
We could validate it in this way (using the standard Applicative validation:
let validate obj =
let open Validate.Applicative in
make_user
<$> required_field string "firstname" obj
<*> required_field string "lastname" obj
<*> required_field integer "age" obj
<*> optional_field_or ~default:false boolean "activated" obj
<*> optional_field string "email" obj
;;
In our previous example, we saw how to use queries on objects. Although this approach works, each validation requires the object to be deconstructed at each stage. Fortunately, it is possible, using associative lists, to deconstruct only once.
let's take our previous type and function (user
and make_user
):
let validate_with_assoc =
object_and (fun assoc ->
let open Validate.Applicative in
make_user
<$> required_assoc string "firstname" assoc
<*> required_assoc string "lastname" assoc
<*> required_assoc integer "age" assoc
<*> optional_assoc_or ~default:false boolean "activated" assoc
<*> optional_assoc string "email" assoc)
;;
The result is identical to the previous one except that this time the object is only deconstructed once.
val optional_assoc :
?case_sensitive:bool ->
(t -> 'a Validate.t) ->
string ->
(string * t) list ->
'a option Validate.t
Same of optional_field
but acting on associatives lists.
val optional_assoc_or :
?case_sensitive:bool ->
default:'a ->
(t -> 'a Validate.t) ->
string ->
(string * t) list ->
'a Validate.t
Same of optional_field_or
but acting on associatives lists.
val required_assoc :
?case_sensitive:bool ->
(t -> 'a Validate.t) ->
string ->
(string * t) list ->
'a Validate.t
Same of required_field
but acting on associatives lists.