Skip to content

Commit 5b081ac

Browse files
committed
Parametrize with 'a IO.t
Allows to support other than 'a Lwt.t.
1 parent 2dec47e commit 5b081ac

File tree

5 files changed

+77
-35
lines changed

5 files changed

+77
-35
lines changed

dream/runtime/ppx_deriving_router_runtime.ml

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
open struct
2+
module IO :
3+
Ppx_deriving_router_runtime_lib.IO with type 'a t = 'a Lwt.t = struct
4+
type 'a t = 'a Lwt.t
5+
6+
let return = Lwt.return
7+
let fail = Lwt.fail
8+
let bind = Lwt.bind
9+
let catch = Lwt_result.catch
10+
end
11+
212
module Request :
3-
Ppx_deriving_router_runtime_lib.REQUEST with type t = Dream.request =
4-
struct
13+
Ppx_deriving_router_runtime_lib.REQUEST
14+
with type 'a IO.t = 'a IO.t
15+
and type t = Dream.request = struct
16+
module IO = IO
17+
518
type t = Dream.request
619

720
let queries = Dream.all_queries
@@ -19,8 +32,11 @@ open struct
1932

2033
module Response :
2134
Ppx_deriving_router_runtime_lib.RESPONSE
22-
with type status = Dream.status
35+
with type 'a IO.t = 'a IO.t
36+
and type status = Dream.status
2337
and type t = Dream.response = struct
38+
module IO = IO
39+
2440
type status = Dream.status
2541

2642
let status_ok : status = `OK
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
include
22
Ppx_deriving_router_runtime_lib.S
3-
with type Request.t = Dream.request
3+
with type 'a IO.t = 'a Lwt.t
4+
and type Request.t = Dream.request
45
and type Response.t = Dream.response
56
and type Response.status = Dream.status
67
and type 'a Return.t = 'a

dream/test/dune

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@
44
(pps ppx_deriving_router.dream melange-json-native.ppx)))
55

66
(cram
7-
(deps ./test.exe (package ppx_deriving_router)))
7+
(deps
8+
./test.exe
9+
(package ppx_deriving_router)))

native/ppx_deriving_router.ml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,15 @@ let td_to_ty_handler param td =
7575
[%type:
7676
[%t td_to_ty (Some param) td] ->
7777
Ppx_deriving_router_runtime.request ->
78-
[%t param] Ppx_deriving_router_runtime.return Lwt.t]
78+
[%t param] Ppx_deriving_router_runtime.return
79+
Ppx_deriving_router_runtime.IO.t]
7980
| None ->
8081
[%type:
8182
[%t td_to_ty param td] ->
8283
Ppx_deriving_router_runtime.request ->
8384
Ppx_deriving_router_runtime.response
8485
Ppx_deriving_router_runtime.return
85-
Lwt.t]
86+
Ppx_deriving_router_runtime.IO.t]
8687

8788
let td_to_ty_enc param td =
8889
let loc = td.ptype_loc in
@@ -125,8 +126,10 @@ let derive_mount td m =
125126
Stdlib.List.map
126127
(fun route ->
127128
let f f req =
128-
Lwt.bind (f req) (fun [%p p [%pat? x, _encode]] ->
129-
Lwt.return [%e make_with_encode encode])
129+
Ppx_deriving_router_runtime.IO.bind (f req)
130+
(fun [%p p [%pat? x, _encode]] ->
131+
Ppx_deriving_router_runtime.IO.return
132+
[%e make_with_encode encode])
130133
in
131134
Ppx_deriving_router_runtime.Handle.prefix_route
132135
[%e elist ~loc (List.map m.m_prefix ~f:(estring ~loc))]
@@ -262,12 +265,14 @@ let derive_path td (exemplar, ctors) =
262265
let pbody, ebody = patt_and_expr ~loc "_body" in
263266
let expr =
264267
match leaf.l_body with
265-
| None -> [%expr Lwt.return [%e make args]]
268+
| None ->
269+
[%expr
270+
Ppx_deriving_router_runtime.IO.return [%e make args]]
266271
| Some (name, body) ->
267272
let name = { loc; txt = Lident name } in
268273
let args = (name, ebody) :: args in
269274
[%expr
270-
Lwt.bind
275+
Ppx_deriving_router_runtime.IO.bind
271276
(Ppx_deriving_router_runtime.Request.body [%e req])
272277
(fun [%p pbody] ->
273278
let [%p pbody] =
@@ -286,7 +291,7 @@ let derive_path td (exemplar, ctors) =
286291
.Invalid_body
287292
msg)
288293
in
289-
Lwt.return [%e make args])]
294+
Ppx_deriving_router_runtime.IO.return [%e make args])]
290295
in
291296
let expr =
292297
[%expr
@@ -433,7 +438,7 @@ let derive_router_td td =
433438
(Some [%pat? p, encode])]
434439
req
435440
->
436-
Lwt.bind (f p req)
441+
Ppx_deriving_router_runtime.IO.bind (f p req)
437442
(Ppx_deriving_router_runtime.Handle.encode encode))];
438443
[%stri
439444
let [%p pvar ~loc (handle_name td)] =

native/runtime/ppx_deriving_router_runtime_lib.ml

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,18 @@ type http_method = [ `DELETE | `GET | `POST | `PUT ]
22

33
module Witness = Ppx_deriving_router_witness
44

5+
module type IO = sig
6+
type 'a t
7+
8+
val return : 'a -> 'a t
9+
val fail : exn -> 'a t
10+
val bind : 'a t -> ('a -> 'b t) -> 'b t
11+
val catch : (unit -> 'a t) -> ('a, exn) result t
12+
end
13+
514
module type REQUEST = sig
15+
module IO : IO
16+
617
type t
718

819
val path : t -> string
@@ -11,14 +22,16 @@ module type REQUEST = sig
1122
val queries : t -> (string * string) list
1223
(* request queries component, url decoded *)
1324

14-
val body : t -> string Lwt.t
25+
val body : t -> string IO.t
1526
(* request body *)
1627

1728
val method_ : t -> http_method
1829
(* request method *)
1930
end
2031

2132
module type RESPONSE = sig
33+
module IO : IO
34+
2235
type status
2336

2437
val status_ok : status
@@ -29,7 +42,7 @@ module type RESPONSE = sig
2942
type t
3043

3144
val respond :
32-
status:status -> headers:(string * string) list -> string -> t Lwt.t
45+
status:status -> headers:(string * string) list -> string -> t IO.t
3346
end
3447

3548
module type RETURN = sig
@@ -42,13 +55,15 @@ module type RETURN = sig
4255
end
4356

4457
module type S = sig
58+
module IO : IO
59+
4560
type json = Yojson.Basic.t
4661

47-
module Request : REQUEST
62+
module Request : REQUEST with module IO = IO
4863

4964
type request = Request.t
5065

51-
module Response : RESPONSE
66+
module Response : RESPONSE with module IO = IO
5267

5368
type response = Response.t
5469

@@ -70,7 +85,7 @@ module type S = sig
7085
| Encode_raw : response encode
7186
| Encode_json : ('a -> json) -> 'a encode
7287

73-
val encode : 'a encode -> 'a return -> response Lwt.t
88+
val encode : 'a encode -> 'a return -> response IO.t
7489

7590
type 'v route =
7691
| Route : ('a, 'v) Routes.path * 'a * ('v -> 'w) -> 'w route
@@ -82,13 +97,13 @@ module type S = sig
8297

8398
type 'a router
8499

85-
val make : (request -> 'a Lwt.t) Routes.router -> 'a router
100+
val make : (request -> 'a IO.t) Routes.router -> 'a router
86101

87102
val handle :
88103
'a router ->
89-
('a -> request -> response Lwt.t) ->
104+
('a -> request -> response IO.t) ->
90105
request ->
91-
response Lwt.t
106+
response IO.t
92107
(** handle request given a router and a dispatcher *)
93108

94109
val dispatch :
@@ -99,25 +114,28 @@ module type S = sig
99114
| `Method_not_allowed
100115
| `Not_found
101116
| `Ok of 'a ]
102-
Lwt.t
117+
IO.t
103118
end
104119
end
105120

106121
module Make
107122
(Request : REQUEST)
108-
(Response : RESPONSE)
123+
(Response : RESPONSE with module IO = Request.IO)
109124
(Return : RETURN with type status = Response.status) :
110125
S
111126
with type Request.t = Request.t
112127
and type Response.t = Response.t
113128
and type Response.status = Response.status
114129
and type 'a Return.t = 'a Return.t
130+
and type 'a IO.t = 'a Request.IO.t
131+
and type 'a IO.t = 'a Response.IO.t
115132
and module Witness = Witness = struct
116133
type json = Yojson.Basic.t
117134
type request = Request.t
118135
type response = Response.t
119136
type 'a return = 'a Return.t
120137

138+
module IO = Request.IO
121139
module Request = Request
122140
module Response = Response
123141
module Return = Return
@@ -135,7 +153,7 @@ module Make
135153
| Encode_raw : response encode
136154
| Encode_json : ('a -> json) -> 'a encode
137155

138-
let encode : type a. a encode -> a Return.t -> response Lwt.t =
156+
let encode : type a. a encode -> a Return.t -> response IO.t =
139157
fun enc x ->
140158
let status =
141159
Option.value ~default:Response.status_ok (Return.status x)
@@ -145,7 +163,7 @@ module Make
145163
| Encode_raw, x -> (
146164
match Return.data x with
147165
| None -> Response.respond ~status ~headers ""
148-
| Some x -> Lwt.return x)
166+
| Some x -> IO.return x)
149167
| Encode_json to_json, x -> (
150168
match Return.data x with
151169
| None -> Response.respond ~status ~headers ""
@@ -169,28 +187,28 @@ module Make
169187

170188
let to_route (Route (path, a, f)) = Routes.(map f (route path a))
171189

172-
type 'a router = (Request.t -> 'a Lwt.t) Routes.router
190+
type 'a router = (Request.t -> 'a IO.t) Routes.router
173191

174192
let make x = x
175193

176194
let dispatch (router : _ router) req =
177195
let target = Request.path req in
178196
match Routes.match' router ~target with
179197
| Routes.FullMatch v | Routes.MatchWithTrailingSlash v ->
180-
Lwt.bind
181-
(Lwt_result.catch (fun () -> v req))
198+
IO.bind
199+
(IO.catch (fun () -> v req))
182200
(function
183-
| Ok v -> Lwt.return (`Ok v)
201+
| Ok v -> IO.return (`Ok v)
184202
| Error (Invalid_query_parameter (x, y)) ->
185-
Lwt.return (`Invalid_query_parameter (x, y))
203+
IO.return (`Invalid_query_parameter (x, y))
186204
| Error (Invalid_body reason) ->
187-
Lwt.return (`Invalid_body reason)
188-
| Error Method_not_allowed -> Lwt.return `Method_not_allowed
189-
| Error exn -> Lwt.fail exn)
190-
| Routes.NoMatch -> Lwt.return `Not_found
205+
IO.return (`Invalid_body reason)
206+
| Error Method_not_allowed -> IO.return `Method_not_allowed
207+
| Error exn -> IO.fail exn)
208+
| Routes.NoMatch -> IO.return `Not_found
191209

192210
let handle (router : _ router) f req =
193-
Lwt.bind (dispatch router req) (function
211+
IO.bind (dispatch router req) (function
194212
| `Ok v -> f v req
195213
| `Invalid_query_parameter (param, msg) ->
196214
Response.respond ~status:Response.status_bad_request

0 commit comments

Comments
 (0)