123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191moduletypeDECODER=sigtypevaluetypefile(** Decoder for Javascript Values *)(** {1 Overview}
Suppose we have the following ocaml types
{[
type sex = Male | Female
type tp = {
name: string;
age: int;
sex: sex
}
]}
and we want to decode the javascript object
{[
{name: "Jonathan", sex: "male", age: 55}
]}
The we can use the following decoder
{[
let decode: tp Decode.t =
let open Decode in
let* name = field "name" string in
let* age = field "age" int in
let* sex =
field
"sex"
(
let* str = string in
match str with
| "male" ->
return Male
| "female" ->
return Female
| _ ->
fail
)
in
return {name; age; sex}
]}
The decoder [decode] decodes any javascript object which has the fields
[name] [age] and [sex] with a value of the appropriate type into the
corresponding ocaml record.
*)(** {1 General}
*)type'at(** ['a t] Type of a decoder which decodes a javascript value into an
optional object of type ['a].
*)valrun:'at->value->'aoption(** [run decoder value] Run the decoder on a javascript value. If the
decoder succeeds with value [a], then return [Some a]. Otherwise return
[None].
*)valreturn:'a->'at(** [return a] Succeed with [a] regardless what the javascript object is. *)valfail:'at(** Fail immediately. *)val(>>=):'at->('a->'bt)->'bt(** [dec >>= f]
Equivalent to
{[
let* v = dec in
f v
]}
*)val(let*):'at->('a->'bt)->'bt(** Combine decoders.
Example:
{[
let* a = dec1 in
dec2 a
]}
First decode the javascript value with decoder [dec1]. In case of
success with the value [a], use decoder [dec2] which can depend on
[a].
[let*] is useful to decode various fields of an object.
{[
let* f1 = field "name1" dec1 in
let* f2 = field "name2" dec2 in
...
return ...
]}
*)valmap:('a->'b)->'at->'bt(** [map f dec] Decode using [dec] and in case of success, map the decoded
value [a] to [f a]. *)val(</>):'at->'at->'at(** [dec1 </> dec2] First try decoder [dec1]. If it succeeds, return the
decoded value. In case [dec1] fails, use [dec2] to decode the javascript
value.
*)(** {1 Basic decoders}
*)valnull:'a->'at(** [null v] If the javascript value is [null], then return [v]. Otherwise
fail.
*)valundefined:'a->'at(** [undefined v] If the javascript value is [undefined], then return [v].
Otherwise fail.
*)valint:intt(** Decode an integer value i.e. a number between [-2^31] and [2^31 - 1].
*)valbool:boolt(** Decode a boolean value. *)valfloat:floatt(** Decode a floating point value i.e. a number. *)valstring:stringt(** Decode a string value. The decoding converts the javascript string from
utf16 into an ocaml utf8 string.
*)valfile_list:filelistt(** Decode a javascript [FileList] object into an ocaml list of [file]. *)(** {1 Complex decoders}
*)valfield:string->'at->'at(** [field name dec] Decode the field named [name] in the javascript object
with the decoder [dec].
*)valarray:'at->'aarrayt(** [array dec] Decode a javascript array into an ocaml array using [dec] to
decode elements.
*)valoption:'at->'aoptiont(** [option dec] In case the javascript object is [null] succeed with [None].
Otherwise use [dec] to decode the object and in case of success wrap the
result with [Some].
Examples:
{[
run (option int) Value.null ~> Some None
run (option int) (Value.int 5) ~> Some (Some 5)
run (option int) (Value.string "a") ~> None
]}
*)end