Module ValidateSource
A module for organizing validations of data structures.
Allows standardized ways of checking for conditions, and keeps track of the location of errors by keeping a path to each error found. Thus, if you were validating the following datastructure:
{ foo = 3; bar = { snoo = 34.5; blue = Snoot - 6 } }One might end up with an error with the error path:
bar.blue.Snoot : value -6 <= bound 0
By convention, the validations for a type defined in module M appear in module M, and have their name prefixed by validate_. E.g., Int.validate_positive.
Here's an example of how you would use validate with a record:
type t =
{ foo : int
; bar : float
}
[@@deriving fields ~iterators:to_list]
let validate t =
let module V = Validate in
let w check = V.field check t in
Fields.to_list ~foo:(w Int.validate_positive) ~bar:(w Float.validate_non_negative)
|> V.of_list
;;And here's an example of how you would use it with a variant type:
type t =
| Foo of int
| Bar of (float * int)
| Snoo of Floogle.t
let validate = function
| Foo i -> V.name "Foo" (Int.validate_positive i)
| Bar p ->
V.name
"Bar"
(V.pair ~fst:Float.validate_positive ~snd:Int.validate_non_negative p)
| Snoo floogle -> V.name "Snoo" (Floogle.validate floogle)
;;The result of a validation. This effectively contains the list of errors, qualified by their location path
To make function signatures easier to read.
To make function signatures easier to read.
(check[@mode portable]) can be read as "a check that returns a Validate.t at mode portable".
If you have f of type (check[@mode portable]), sometimes the type checker takes some convincing to treat it as a check, even though a returning-at-portable function is morally a subtype of a returning-at-nonportable function. Writing (fun x -> f x) should be enough to convert the (check[@mode portable]) into a check.
A result containing no errors.
A result containing a single error.
This can be used with the %sexp extension.
Like sprintf or failwithf but produces a t instead of a string or exception.
Combines multiple results, merging errors.
Extends location path by one name.
Extends location path by one lazy name, which will be forced only in the case of failure.
val lazy_name_list :
Base.string Base.Lazy.t ->
Validate.t Base.list ->
Validate.t @@ portablefail_fn err returns a function that always returns fail, with err as the error message. (Note that there is no pass_fn so as to discourage people from ignoring the type of the value being passed unconditionally irrespective of type.)
Checks for unconditionally passing a bool.
Checks for unconditionally passing a unit.
protect f x applies the validation f to x, catching any exceptions and returning them as errors.
try_with f runs f catching any exceptions and returning them as errors.
Returns a list of formatted error strings, which include both the error message and the path to the error.
If the result contains any errors, then raises an exception with a formatted error message containing a message for every error.
Returns an error if validation fails.
val field :
('a : value_or_null) 'record. 'a Validate.check ->
'record ->
([> `Read ], 'record, 'a) Base.Field.t_with_perm ->
Validate.t @@ portableUsed for validating an individual field. Should be used with Fields.to_list.
val field_direct :
('a : value_or_null) 'record. 'a Validate.check ->
([> `Read ], 'record, 'a) Base.Field.t_with_perm ->
'record ->
'a ->
Validate.t @@ portableUsed for validating an individual field. Should be used with Fields.Direct.to_list.
val field_folder :
'a Validate.check ->
'record ->
Validate.t Base.list ->
([> `Read ], 'record, 'a) Base.Field.t_with_perm ->
Validate.t Base.list @@ portableCreates a function for use in a Fields.fold.
val portable_field_folder :
'a Validate.check__portable ->
'record ->
Validate.t Base.portable Base.list ->
([> `Read ], 'record, 'a) Base.Field.t_with_perm ->
Validate.t Base.portable Base.list @@ portableLike field_folder, but for producing a list of portable ts. It's marginally easier to use directly when folding over fields to produce a portable result.
val field_direct_folder :
'a Validate.check ->
(Validate.t Base.list ->
([> `Read ], 'record, 'a) Base.Field.t_with_perm ->
'record ->
'a ->
Validate.t Base.list)
Base.Staged.t @@ portableCreates a function for use in a Fields.Direct.fold.
Combines a list of validation functions into one that does all validations.
val of_result :
('a -> (Base.unit, Base.string) Base.Result.t) ->
'a Validate.check__portable @@ portableCreates a validation function from a function that produces a Result.t.
Creates a validation function from a function that produces a bool.
val lazy_booltest :
('a -> Base.bool) ->
if_false:Base.string Base.Lazy.t ->
'a Validate.check @@ portableCreates a validation function from a function that produces a bool. Forces the name only when validation fails.
val pair :
fst:'a Validate.check ->
snd:'b Validate.check ->
('a * 'b) Validate.check @@ portableValidation functions for particular data types.
Validates a list, naming each element by its position in the list (where the first position is 1, not 0).
val list :
name:('a -> Base.string) ->
'a Validate.check ->
'a Base.list Validate.check @@ portableValidates a list, naming each element using a user-defined function for computing the name.
val alist :
name:('a -> Base.string) ->
'b Validate.check ->
('a * 'b) Base.list Validate.check @@ portableValidates an association list, naming each element using a user-defined function for computing the name.
val bounded :
name:('a -> Base.string) ->
lower:'a Base.Maybe_bound.t ->
upper:'a Base.Maybe_bound.t ->
compare:('a -> 'a -> Base.int) ->
'a Validate.check__portable @@ portable