Source file reader_string_file.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
module type Reader_string_file = sig
type json
val json_of_string : string -> (json, string) result
val json_of_string_exn : string -> json
val json_of_file : string -> (json, string) result
val json_of_file_exn : string -> json
val json_of_channel : in_channel -> (json, string) result
val json_of_channel_exn : in_channel -> json
val json_of_function : (bytes -> int -> int) -> (json, string) result
val json_of_function_exn : (bytes -> int -> int) -> json
val json_of_lexbuf : Lexing.lexbuf -> (json, string) result
val json_of_lexbuf_exn : Lexing.lexbuf -> json
val of_string : string -> json
val of_file : string -> json
val of_channel : in_channel -> json
val of_function : (bytes -> int -> int) -> json
val json_of_string_error_info : string -> (json, Error_info.t) result
val json_of_file_error_info : string -> (json, Error_info.t) result
val json_of_channel_error_info : in_channel -> (json, Error_info.t) result
val json_of_function_error_info : (bytes -> int -> int) -> (json, Error_info.t) result
val json_of_lexbuf_error_info : Lexing.lexbuf -> (json, Error_info.t) result
val json_of_lexbuf_error_info_compat : ?stream:bool -> Lexing.lexbuf -> (json option, Error_info.t) result
val stream_from_string : string -> json Stream.t
val stream_from_channel : ?fin:(unit -> unit) -> in_channel -> json Stream.t
val stream_from_file : string -> json Stream.t
val stream_from_function : (bytes -> int -> int) -> json Stream.t
val stream_from_lexbuf : Lexing.lexbuf -> json Stream.t
val stream_from_string_error_info : string -> json Stream.t
val stream_from_channel_error_info : ?fin:(unit -> unit) -> in_channel -> json Stream.t
val stream_from_file_error_info : string -> json Stream.t
val stream_from_function_error_info : (bytes -> int -> int) -> json Stream.t
val stream_from_lexbuf_error_info : Lexing.lexbuf -> json Stream.t
end
module Make (Lexxer : Compliant_lexxer.Lex ) (Parser : Parser.Parser) : Reader_string_file
with type json = Parser.Compliance.json
= struct
type json = Parser.Compliance.json
let read_json' ~lexbuf =
let reader () = Lexxer.read lexbuf in
match Parser.decode ~reader with
| Ok None -> Error "empty input"
| Ok (Some res) -> begin
match reader () with
| EOF -> Ok res
| exception Lexxer_utils.Lex_error err -> Error err
| tok -> Error ("junk after end of JSON value: " ^ (Token_utils.token_to_string tok))
end
| Error s -> Error s
let read_json ~lexbuf =
match read_json' ~lexbuf with
| Ok _ as res -> res
| Error s ->
let err_info = Error_info.create_from_lexbuf lexbuf s in
Error (Error_info.to_string err_info)
let json_of_string s =
let lexbuf = Lexing.from_string s in
read_json ~lexbuf
let json_of_string_exn s =
match json_of_string s with
| Ok res -> res
| Error s -> raise (Failure s)
let of_string s = json_of_string_exn s
let json_of_file filename =
try begin
let inc = open_in filename in
let lexbuf = Lexing.from_channel inc in
let res = read_json ~lexbuf in
close_in inc;
res
end
with Sys_error err -> Error err
let json_of_file_exn filename =
match json_of_file filename with
| Ok res -> res
| Error s -> raise (Failure s)
let json_of_channel inc =
let lexbuf = Lexing.from_channel inc in
read_json ~lexbuf
let json_of_channel_exn inc =
match json_of_channel inc with
| Ok res -> res
| Error s -> raise (Failure s)
let json_of_function f =
let lexbuf = Lexing.from_function f in
read_json ~lexbuf
let json_of_lexbuf lexbuf =
read_json ~lexbuf
let json_of_lexbuf_exn lexbuf =
match json_of_lexbuf lexbuf with
| Ok res -> res
| Error s -> raise (Failure s)
let json_of_function_exn f =
match json_of_function f with
| Ok res -> res
| Error s -> raise (Failure s)
let of_file = json_of_file_exn
let of_channel = json_of_channel_exn
let of_function = json_of_function_exn
let read_json_error_info ~lexbuf =
match read_json' ~lexbuf with
| Ok _ as res -> res
| Error err ->
let err_info = Error_info.create_from_lexbuf lexbuf err in
Error err_info
let json_of_string_error_info s =
let lexbuf = Lexing.from_string s in
read_json_error_info ~lexbuf
let json_of_channel_error_info inc =
let lexbuf = Lexing.from_channel inc in
read_json_error_info ~lexbuf
let json_of_file_error_info filename =
try begin
let inc = open_in filename in
let res = json_of_channel_error_info inc in
close_in inc;
res
end
with Sys_error err -> Error { Error_info.line = 0; start_char = 0; end_char = 0; msg = err }
let json_of_function_error_info f =
let lexbuf = Lexing.from_function f in
read_json_error_info ~lexbuf
let json_of_lexbuf_error_info lexbuf =
read_json_error_info ~lexbuf
let json_of_lexbuf_error_info_compat ?(stream = false) lexbuf =
let reader () = Lexxer.read lexbuf in
let res = match Parser.decode ~reader with
| Ok None -> if stream then Ok None else Error "empty input"
| Ok (Some res) -> begin
match stream with
| true -> Ok (Some res)
| false -> begin
match reader () with
| EOF -> Ok (Some res)
| exception Lexxer_utils.Lex_error err -> Error err
| tok -> Error ("junk after end of JSON value: " ^ (Token_utils.token_to_string tok))
end
end
| Error s -> Error s
in
match res with
| Ok res -> Ok res
| Error s ->
let err_info = Error_info.create_from_lexbuf lexbuf s in
Error err_info
let read_json_stream ~fin ~lexbuf =
let reader () = Lexxer.read lexbuf in
let f _i =
match Parser.decode ~reader with
| Ok None -> fin (); None
| Ok (Some res) -> Some res
| Error err ->
let () = fin () in
let err_info = Error_info.create_from_lexbuf lexbuf err in
let msg = Error_info.to_string err_info in
raise (Failure msg)
in
Stream.from f
let stream_from_string s =
let lexbuf = Lexing.from_string s in
read_json_stream ~fin:(fun () -> ()) ~lexbuf
let stream_from_channel ?(fin = fun () -> ()) inc =
let lexbuf = Lexing.from_channel inc in
read_json_stream ~fin ~lexbuf
let stream_from_function f =
let lexbuf = Lexing.from_function f in
read_json_stream ~fin:(fun () -> ()) ~lexbuf
let stream_from_file filename =
let inc = open_in filename in
stream_from_channel ~fin:(fun () -> close_in inc) inc
let stream_from_lexbuf lexbuf =
read_json_stream ~fin:(fun () -> ()) ~lexbuf
let read_json_stream_error_info ~fin ~lexbuf =
let reader () = Lexxer.read lexbuf in
let f _i =
match Parser.decode ~reader with
| Ok None -> fin (); None
| Ok (Some res) -> Some res
| Error err ->
let () = fin () in
let err_info = Error_info.create_from_lexbuf lexbuf err in
raise (Error_info.Json_error_info err_info)
in
Stream.from f
let stream_from_string_error_info s =
let lexbuf = Lexing.from_string s in
read_json_stream_error_info ~fin:(fun () -> ()) ~lexbuf
let stream_from_channel_error_info ?(fin = fun () -> ()) inc =
let lexbuf = Lexing.from_channel inc in
read_json_stream_error_info ~fin ~lexbuf
let stream_from_function_error_info f =
let lexbuf = Lexing.from_function f in
read_json_stream_error_info ~fin:(fun () -> ()) ~lexbuf
let stream_from_file_error_info filename =
let inc = open_in filename in
stream_from_channel_error_info ~fin:(fun () -> close_in inc) inc
let stream_from_lexbuf_error_info lexbuf =
read_json_stream_error_info ~fin:(fun () -> ()) ~lexbuf
end