Source file encode.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
type env =
  { encoder : Jsonm.encoder
  ; on_partial : unit -> unit
  }

let make_env
    ~encoder ?(on_partial = fun () -> failwith "Not expecting `Partial") () =
  { encoder; on_partial }


let make_encoder' x { encoder; on_partial } =
  let rec await () =
    on_partial () ;
    match Jsonm.encode encoder `Await with `Ok -> () | `Partial -> await ()
  in
  match Jsonm.encode encoder x with `Ok -> () | `Partial -> await ()


let make_encoder l env = make_encoder' (`Lexeme l) env

type v = env -> unit

let ( >> ) (v1 : v) (v2 : v) : v =
 fun env ->
  v1 env ;
  v2 env


let iter encode xs : v = fun env -> xs |> List.iter (fun x -> encode x env)

let object_start = make_encoder `Os

let name x = make_encoder (`Name x)

let object_end = make_encoder `Oe

let array_start = make_encoder `As

let array_end = make_encoder `Ae

let end_ = make_encoder' `End

module Jsonm_encodeable = struct
  type value = v

  let to_string (_v : value) : string = failwith "Not implemented"

  let of_string x : value = make_encoder (`String x)

  let of_int x : value = make_encoder (`Float (float_of_int x))

  let of_float x : value = make_encoder (`Float x)

  let of_bool x : value = make_encoder (`Bool x)

  let null : value = make_encoder `Null

  let of_list (xs : value list) : value =
    array_start >> iter (fun x -> x) xs >> array_end


  let of_key_value_pairs (xs : (value * value) list) : value =
    object_start >> iter (fun (k, v) -> k >> v) xs >> object_end
end

include Decoders.Encode.Make (Jsonm_encodeable)

(* Override with more efficient implementations *)

let list encode xs = array_start >> iter encode xs >> array_end

let obj (xs : (string * value) list) : value =
  object_start >> iter (fun (k, v) -> name k >> v) xs >> object_end


let encode_value encoder x = encoder x >> end_

let encode_string encoder x =
  let b = Buffer.create 16 in
  let env = make_env ~encoder:(Jsonm.encoder ~minify:true (`Buffer b)) () in
  let () = encode_value encoder x env in
  Buffer.contents b