mirror of
https://github.com/aantron/dream.git
synced 2025-12-31 00:03:52 -05:00
Constrain message types in body API
This commit is contained in:
parent
c5ecca90af
commit
3a7a07a86c
@ -89,36 +89,31 @@ let bigstring_replacement = {|
|
||||
|}
|
||||
|
||||
let next_expected = {|<div class="spec value" id="val-next">
|
||||
<a href="#val-next" class="anchor"></a><code><span><span class="keyword">val</span> next : <span>bigstring:<span>(<span><a href="#type-bigstring">bigstring</a> <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span>?string:<span>(<span>string <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span>
|
||||
<span>?flush:<span>(<span>unit <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span>close:<span>(<span>unit <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span>exn:<span>(<span>exn <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">_</span> <a href="#type-message">message</a></span> <span class="arrow">-></span></span> unit</span></code>
|
||||
<a href="#val-next" class="anchor"></a><code><span><span class="keyword">val</span> next : <span>bigstring:<span>(<span><a href="#type-bigstring">bigstring</a> <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span>close:<span>(<span>unit <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span>exn:<span>(<span>exn <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span>
|
||||
<span><a href="#type-request">request</a> <span class="arrow">-></span></span> unit</span></code>
|
||||
</div>
|
||||
|}
|
||||
|
||||
let next_replacement = {|
|
||||
<pre><span class="keyword">val</span> next :
|
||||
bigstring:(<a href="#type-bigstring">bigstring</a> -> int -> int -> unit) ->
|
||||
?string:(string -> int -> int -> unit) ->
|
||||
?flush:(unit -> unit) ->
|
||||
close:(unit -> unit) ->
|
||||
exn:(exn -> unit) ->
|
||||
_ <a href="#type-message">message</a> ->
|
||||
<a href="#type-request">request</a> ->
|
||||
unit
|
||||
</ore>
|
||||
</pre>
|
||||
|}
|
||||
|
||||
(* let body_stream_bigstring_expected = {|<div class="spec value" id="val-body_stream_bigstring">
|
||||
<a href="#val-body_stream_bigstring" class="anchor"></a><code><span><span class="keyword">val</span> body_stream_bigstring : <span><span>(<span><a href="#type-bigstring">bigstring</a> <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><span>(<span>unit <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">_</span> <a href="#type-message">message</a></span> <span class="arrow">-></span></span> unit</span></code>
|
||||
let write_bigstring_expected = {|<div class="spec value" id="val-write_bigstring">
|
||||
<a href="#val-write_bigstring" class="anchor"></a><code><span><span class="keyword">val</span> write_bigstring : <span><a href="#type-bigstring">bigstring</a> <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> <span><a href="#type-response">response</a> <span class="arrow">-></span></span> <span>unit <a href="#type-promise">promise</a></span></span></code>
|
||||
</div>
|
||||
|}
|
||||
|
||||
let body_stream_bigstring_replacement = {|
|
||||
<pre><span class="keyword">val</span> body_stream_bigstring :
|
||||
(<a href="#type-bigstring">bigstring</a> -> int -> int -> unit) ->
|
||||
(unit -> unit) ->
|
||||
(_ <a href="#type-message">message</a>) ->
|
||||
unit
|
||||
let write_bigstring_replacement = {|
|
||||
<pre><span class="keyword">val</span> write_bigstring :
|
||||
<a href="#type-bigstring">bigstring</a> -> int -> int -> <a href="#type-response">response</a> -> unit <a href="#type-promise">promise</a>
|
||||
</pre>
|
||||
|} *)
|
||||
|}
|
||||
|
||||
let form_expected = {|<div class="spec type" id="type-form">
|
||||
<a href="#type-form" class="anchor"></a><code><span><span class="keyword">type</span> form</span><span> = </span><span>[ </span></code>
|
||||
@ -516,14 +511,14 @@ let pretty_print_signatures soup =
|
||||
Soup.replace (next $ "> code") (Soup.parse next_replacement);
|
||||
Soup.add_class "multiline" next);
|
||||
|
||||
(* let body_stream_bigstring = soup $ "#val-body_stream_bigstring" in
|
||||
let write_bigstring = soup $ "#val-write_bigstring" in
|
||||
if_expected
|
||||
body_stream_bigstring_expected
|
||||
(fun () -> pretty_print body_stream_bigstring)
|
||||
write_bigstring_expected
|
||||
(fun () -> pretty_print write_bigstring)
|
||||
(fun () ->
|
||||
Soup.replace
|
||||
(body_stream_bigstring $ "> code")
|
||||
(Soup.parse body_stream_bigstring_replacement)); *)
|
||||
(write_bigstring $ "> code") (Soup.parse write_bigstring_replacement);
|
||||
Soup.add_class "multiline" write_bigstring);
|
||||
|
||||
let form = soup $ "#type-form" in
|
||||
if_expected
|
||||
|
||||
@ -13,6 +13,10 @@ end
|
||||
|
||||
include Dream__pure.Inmost
|
||||
|
||||
(* Eliminate optional arguments from the public interface for now. *)
|
||||
let next ~bigstring ~close ~exn request =
|
||||
next ~bigstring ~close ~exn request
|
||||
|
||||
include Dream__middleware.Log
|
||||
include Dream__middleware.Echo
|
||||
|
||||
|
||||
@ -550,30 +550,29 @@ val all_cookies : request -> (string * string) list
|
||||
(* TODO Will need mappers, etc. *)
|
||||
(** {1 Bodies} *)
|
||||
|
||||
val body : _ message -> string promise
|
||||
(** Retrieves the entire message body. {!Dream.body} stores a reference to the
|
||||
result string in the message, so {!Dream.body} can be used multiple
|
||||
val body : request -> string promise
|
||||
(** Retrieves the entire request body. {!Dream.body} stores a reference to the
|
||||
result string in the request, so {!Dream.body} can be used multiple
|
||||
times. *)
|
||||
|
||||
val with_body : string -> 'a message -> 'a message
|
||||
(** Replaces the message body, creating a new message. *)
|
||||
val with_body : string -> response -> response
|
||||
(** Replaces the response body. *)
|
||||
|
||||
(** {2 Streaming} *)
|
||||
|
||||
(* TODO Rename to stream_body. *)
|
||||
val read : _ message -> string option promise
|
||||
(** Retrieves part of the message body. The promise is fulfilled with [None] if
|
||||
the body is finished. The chunk is not buffered by Dream, so it can only be
|
||||
read once. *)
|
||||
val read : request -> string option promise
|
||||
(** Retrieves a chunk of the request body. The promise is fulfilled with [None]
|
||||
if the body is finished. The chunk is not buffered by Dream, so it can only
|
||||
be read once. *)
|
||||
|
||||
(* val with_body_stream :
|
||||
(unit -> string option promise) -> 'a message -> 'a message *)
|
||||
(* TODO Could still use a Dream.respond_with_stream helper. *)
|
||||
(* TODO Can still use a multishot, pull stream? *)
|
||||
val with_stream : 'a message -> 'a message
|
||||
(** Makes the message ready for stream writing with {!Dream.write}. If the
|
||||
message is a response, you should return it from your handler soon after
|
||||
— only one call to {!Dream.write} will proceed until then. *)
|
||||
val with_stream : response -> response
|
||||
(** Makes the response ready for stream writing with {!Dream.write}. You should
|
||||
return it from your handler soon after — only one call to {!Dream.write}
|
||||
will be accepted before then, and none will actually proceed. *)
|
||||
|
||||
(* [Dream.with_body_stream f message] creates a new message, with a stream
|
||||
body represented by the function [f]. If the message is a response, after
|
||||
@ -589,20 +588,19 @@ val with_stream : 'a message -> 'a message
|
||||
(* TODO It would be nice if the returned message was already wrapped in a
|
||||
promise. Does that preclude anything useful, however? *)
|
||||
|
||||
val write : string -> _ message -> unit promise
|
||||
(** Streams out the string. The promise is fulfilled when the stream can accept
|
||||
more writes. *)
|
||||
val write : string -> response -> unit promise
|
||||
(** Streams out the string. The promise is fulfilled when the response can
|
||||
accept more writes. *)
|
||||
|
||||
val flush : _ message -> unit promise
|
||||
(** Flushes write buffers. If the message is a response, data is sent to the
|
||||
client. *)
|
||||
val flush : response -> unit promise
|
||||
(** Flushes write buffers. Data is sent to the client. *)
|
||||
|
||||
val close_stream : _ message -> unit promise
|
||||
(** Finishes the write stream. *)
|
||||
val close_stream : response -> unit promise
|
||||
(** Finishes the response stream. *)
|
||||
(* TODO close_stream or close_body? *)
|
||||
|
||||
(**/**)
|
||||
val has_body : _ message -> bool
|
||||
(* val has_body : _ message -> bool *)
|
||||
(** Evalutes to [true] if the given message either has a body that has been
|
||||
streamed and has positive length, or a body that has not been streamed yet.
|
||||
This function does not stream the body — it could return [true], and later
|
||||
@ -630,25 +628,20 @@ type bigstring =
|
||||
(* TODO Is the final unit necessary. *)
|
||||
val next :
|
||||
bigstring:(bigstring -> int -> int -> unit) ->
|
||||
?string:(string -> int -> int -> unit) ->
|
||||
?flush:(unit -> unit) ->
|
||||
(* ?string:(string -> int -> int -> unit) ->
|
||||
?flush:(unit -> unit) -> *)
|
||||
close:(unit -> unit) ->
|
||||
exn:(exn -> unit) ->
|
||||
_ message ->
|
||||
request ->
|
||||
unit
|
||||
(** Waits for the next event on the stream, and calls:
|
||||
(** Waits for the next stream event, and calls:
|
||||
|
||||
- [~bigstring] with an offset and length, if a {!bigstring} is written.
|
||||
- [~string] if a string is written.
|
||||
- [~flush] if flush is requested.
|
||||
- [~close] if close is requested.
|
||||
- [~exn] to report an exception.
|
||||
- [~exn] to report an exception. *)
|
||||
|
||||
If the message is a request provided by Dream, [~string] and [~flush] will
|
||||
never be called, so they are optional. *)
|
||||
|
||||
val write_bigstring : bigstring -> int -> int -> _ message -> unit promise
|
||||
(** Streams out the bigstring slice. *)
|
||||
val write_bigstring : bigstring -> int -> int -> response -> unit promise
|
||||
(** Streams out the {!bigstring} slice. *)
|
||||
|
||||
(**/**)
|
||||
(* TODO Format after settling on it. *)
|
||||
|
||||
@ -151,7 +151,7 @@ let%expect_test _ =
|
||||
let next message =
|
||||
let until_done, signal_done = Lwt.wait () in
|
||||
let rec next accumulator =
|
||||
Dream.next
|
||||
Dream__pure.Inmost.next
|
||||
~bigstring:(fun data start length ->
|
||||
next
|
||||
((Lwt_bytes.to_string
|
||||
@ -161,7 +161,7 @@ let next message =
|
||||
((String.sub data start length)::accumulator))
|
||||
~close:(fun () -> Lwt.wakeup_later signal_done (List.rev accumulator))
|
||||
~exn:ignore
|
||||
message
|
||||
(Obj.magic message)
|
||||
in
|
||||
next [];
|
||||
Lwt_main.run until_done
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user