Module Base.Decode

Decode javascript values into ocaml values.

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.

API

type 'a t = Value.t -> 'a option

'a t Type of a decoder which decodes a javascript value into an optional object of type 'a.

Returns an object of type 'a, if the decoder can decode the javascript value into an object of type 'a. Otherwise returns None.

val return : 'a -> 'a t

return a Return a regardless what the javascript object is.

val fail : 'a t

Immediately fail i.e. return None.

val let* : 'a t -> ('a -> 'b t) -> 'b t

Combinate decoders.

Example:

let* a = decoder1 in
decoder1 a

First decode the javascript value with decoder decoder1. In case of success with the value a, use decoder decoder2 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 ...
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t

dec >>= f

Equivalent to

let* v = dec in
f v
val (</>) : 'a t -> 'a t -> 'a t

dec1 </> dec2 First try decoder dec1. If it succeeds, return the decoded value. In case dec1 fails, use dec2 to decode the javascript value.

val map : ('a -> 'b) -> 'a t -> 'b t

map f dec Decode using dec and in case of success, map the decoded value by f.

val null : 'a -> 'a t

null v If the javascript value is null, then return v. Otherwise fail.

val undefined : 'a -> 'a t

undefined v If the javascript value is undefined, then return v. Otherwise fail.

val float : float t

Decode a floating point value i.e. a number.

val int : int t

Decode an integer value i.e. a number between -2^31 and 2^31 - 1.

val bool : bool t

Decode a boolean value.

val string : string t

Decode a string value. The decoding converts the javascript string from utf16 into an ocaml utf8 string.

val _function : (Value.t array -> Value.t) t

Decode a javascript function into an ocaml function.

Since javascript function can accept any number of arguments, the returned function is an ocaml function which accepts an array of javascript values and returns a javascript value.

The function can use decoders to decode its arguments and use the module Value to generate the result.

val _method : (Value.t -> Value.t array -> Value.t) t

Decode a javascript method into an ocaml function.

The decoded function accepts a javascript value which is bound to this and and array of javascript value arguments.

A call f obj args is compiled to the javascript call f.apply(obj,args).

If the javascript function is not a method, then it ignores the object argument.

val field : string -> 'a t -> 'a t

field name dec Decode the field named name in the javascript object with the decoder dec.

val array : 'a t -> 'a array t

array dec Decode a javascript array into an ocaml array using dec to decode elements.

val option : 'a t -> 'a option t

option dec In case the javascript object is null return Some None. Otherwise use dec to decode the object and in case of success wrap the result with Some.

Examples:

(option int) Value.null         ~>      Some None
(option int) (Value.int 6)      ~>      Some (Some 5)
(option int) (Value.string "a") ~>      None