Skip to content

Commit efc6cb1

Browse files
authored
Merge pull request #77 from benbellick/add-tuple-helpers
Add tuple helpers
2 parents 59c0dfb + 1cf35a3 commit efc6cb1

File tree

4 files changed

+107
-2
lines changed

4 files changed

+107
-2
lines changed

src-otoml/dune

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
(library
32
(name decoders_otoml)
43
(public_name decoders-otoml)

src/decode.ml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,38 @@ module Make (Decodeable : Decodeable) :
329329
(fail "Expected a list").dec value
330330

331331

332+
let ( >>=:: ) fst rest = uncons rest fst
333+
334+
let empty_list =
335+
Decoder.of_decode_fun
336+
@@ fun value ->
337+
match Decodeable.get_list value with
338+
| Some [] ->
339+
Ok ()
340+
| Some _ ->
341+
(fail "Expected an empty list").dec value
342+
| None ->
343+
(fail "Expected a list").dec value
344+
345+
346+
let tuple2 d0 d1 =
347+
d0 >>=:: fun arg0 -> d1 >>=:: fun arg1 -> succeed (arg0, arg1)
348+
349+
350+
let tuple3 d0 d1 d2 =
351+
d0
352+
>>=:: fun arg0 ->
353+
d1 >>=:: fun arg1 -> d2 >>=:: fun arg2 -> succeed (arg0, arg1, arg2)
354+
355+
356+
let tuple4 d0 d1 d2 d3 =
357+
d0
358+
>>=:: fun arg0 ->
359+
d1
360+
>>=:: fun arg1 ->
361+
d2 >>=:: fun arg2 -> d3 >>=:: fun arg3 -> succeed (arg0, arg1, arg2, arg3)
362+
363+
332364
let rec at : string list -> 'a decoder -> 'a decoder =
333365
fun path decoder ->
334366
match path with

src/sig.ml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,36 @@ module type S = sig
117117
118118
(If you squint, the uncons operator [>>=::] kind of looks like the cons
119119
operator [::].)
120-
*)
120+
*)
121+
122+
val empty_list : unit decoder
123+
124+
val tuple2 : 'a decoder -> 'b decoder -> ('a * 'b) decoder
125+
(** Decode a collection into an OCaml 2-tuple.
126+
127+
For example, to decode this json:
128+
129+
{[
130+
[true, "string"]
131+
]}
132+
133+
we can use this decoder:
134+
135+
{[
136+
tuple2 bool string
137+
]}
138+
*)
139+
140+
val tuple3 : 'a decoder -> 'b decoder -> 'c decoder -> ('a * 'b * 'c) decoder
141+
(** Decode a collection into an OCaml 3-tuple. *)
142+
143+
val tuple4 :
144+
'a decoder
145+
-> 'b decoder
146+
-> 'c decoder
147+
-> 'd decoder
148+
-> ('a * 'b * 'c * 'd) decoder
149+
(** Decode a collection into an OCaml 4-tuple. *)
121150

122151
(** {1 Object primitives} *)
123152

test-yojson/main.ml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,58 @@ let yojson_basic_suite =
172172
Format.asprintf "@,@[%a@]" pp_error e )
173173
in
174174

175+
let tupleN_test =
176+
"TupleN"
177+
>:: fun _ ->
178+
let module M = struct
179+
type t2 = int * string
180+
181+
let t2_to_string ((i, s) : t2) = Printf.sprintf "(%i, %s)" i s
182+
end in
183+
let open M in
184+
decoder_test
185+
()
186+
~decoder:(tuple2 int string)
187+
~input:{|[149, "my string"]|}
188+
~expected:(149, "my string")
189+
~printer:t2_to_string
190+
in
191+
let empty_list_test =
192+
"empty_list"
193+
>:: fun _ ->
194+
decoder_test
195+
()
196+
~decoder:empty_list
197+
~input:{|[]|}
198+
~expected:()
199+
~printer:(fun () -> Printf.sprintf "()")
200+
in
201+
let empty_list_nonempty_test =
202+
"empty_list_enforced"
203+
>:: fun _ ->
204+
let input = {|[1, 2]|} in
205+
let expected_error =
206+
let open Decoders in
207+
Error.make ~context:(`List [ `Int 1; `Int 2 ]) "Expected an empty list"
208+
in
209+
match decode_string empty_list input with
210+
| Ok _ ->
211+
assert_string "Expected an error"
212+
| Error error ->
213+
assert_equal expected_error error ~printer:(fun e ->
214+
Format.asprintf "@,@[%a@]" pp_error e )
215+
in
216+
175217
"Yojson.Basic"
176218
>::: [ list_string_test
177219
; array_string_test
178220
; fix_one_of_test
179221
; mut_rec_test
180222
; string_or_floatlit_test
181223
; grouping_errors_test
224+
; tupleN_test
225+
; empty_list_test
226+
; empty_list_nonempty_test
182227
]
183228

184229

0 commit comments

Comments
 (0)