Source file registration.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
type id = string
type t =
| Record : {
encoding: 'a Encoding.t;
description: string option;
pp: (Format.formatter -> 'a -> unit) option;
}
-> t
module EncodingTable = Map.Make (String)
let table = ref EncodingTable.empty
let description (Record {description; _}) = description
let slice (Record {encoding; _}) bytes =
Binary_slicer.slice_string encoding bytes
let slice_all bytes =
EncodingTable.fold
(fun enc_id (Record {encoding; _}) sliced ->
try
let _ = Binary_reader.of_string_exn encoding bytes in
let slice = Binary_slicer.slice_string_exn encoding bytes in
(enc_id, slice) :: sliced
with
| (Out_of_memory | Stack_overflow) as e -> raise e
| _ -> sliced)
!table
[]
let json_schema (Record {encoding; _}) =
let json_schema = Json.schema encoding in
json_schema
let binary_schema (Record {encoding; _}) =
let binary_schema = Binary_description.describe encoding in
binary_schema
let json_pretty_printer (Record {encoding; pp; _}) fmt json =
match pp with
| Some pp ->
let json = Json.destruct encoding json in
Format.fprintf fmt "%a" pp json
| None -> Format.fprintf fmt "%a" Json.pp json
let binary_pretty_printer (Record {encoding; pp; _}) fmt bytes =
let data = Binary_reader.of_bytes_exn encoding bytes in
match pp with
| Some pp -> Format.fprintf fmt "%a" pp data
| None ->
let json = Json.construct encoding data in
Format.fprintf fmt "%a" Json.pp json
let rec lookup_id_descr ({encoding; _} : 'a Encoding.t) =
match encoding with
| Splitted {encoding; _}
| Dynamic_size {encoding; _}
| Check_size {encoding; _} ->
lookup_id_descr encoding
| Describe {id; description; _} -> Some (id, description)
| _ -> None
let register ?pp encoding =
match lookup_id_descr encoding with
| None ->
invalid_arg "Data_encoding.Registration.register: non def(in)ed encoding"
| Some (id, description) ->
table :=
EncodingTable.update
id
(function
| None ->
let record = Record {encoding; description; pp} in
Some record
| Some _ ->
Format.kasprintf
invalid_arg
"Encoding %s previously registered"
id)
!table
let find id = EncodingTable.find_opt id !table
let list () = EncodingTable.bindings !table
let bytes_of_json (Record {encoding; _}) json =
let data = Json.destruct encoding json in
Binary_writer.to_bytes_opt encoding data
let json_of_bytes (Record {encoding; _}) bytes =
match Binary_reader.of_bytes_opt encoding bytes with
| Some v -> Some (Json.construct encoding v)
| None -> None