aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-06-25 15:26:58 +0200
committerLoïc Hoguin <[email protected]>2018-06-25 15:26:58 +0200
commit93b2b897cde238506c803faad4d1602d79dba7c9 (patch)
tree979cf936761447b13abdd251752cf8dd44877e0b
parentaf88cb78fc0dffb27fd9ab09659a6ba595493c1a (diff)
downloadcowlib-93b2b897cde238506c803faad4d1602d79dba7c9.tar.gz
cowlib-93b2b897cde238506c803faad4d1602d79dba7c9.tar.bz2
cowlib-93b2b897cde238506c803faad4d1602d79dba7c9.zip
Add building of SSE events
-rw-r--r--src/cow_sse.erl83
1 files changed, 81 insertions, 2 deletions
diff --git a/src/cow_sse.erl b/src/cow_sse.erl
index dc195a1..9d4a91e 100644
--- a/src/cow_sse.erl
+++ b/src/cow_sse.erl
@@ -16,6 +16,8 @@
-export([init/0]).
-export([parse/2]).
+-export([events/1]).
+-export([event/1]).
-record(state, {
state_name = bom :: bom | events,
@@ -28,12 +30,21 @@
-type state() :: #state{}.
-export_type([state/0]).
--type event() :: #{
+-type parsed_event() :: #{
last_event_id := binary(),
event_type := binary(),
data := iolist()
}.
+-type event() :: #{
+ comment => iodata(),
+ data => iodata(),
+ event => iodata() | atom(),
+ id => iodata(),
+ retry => non_neg_integer()
+}.
+-export_type([event/0]).
+
-spec init() -> state().
init() ->
#state{}.
@@ -41,7 +52,7 @@ init() ->
%% @todo Add a function to retrieve the retry value from the state.
-spec parse(binary(), state())
- -> {event, event(), State} | {more, State}.
+ -> {event, parsed_event(), State} | {more, State}.
parse(Data0, State=#state{state_name=bom, buffer=Buffer}) ->
Data1 = case Buffer of
<<>> -> Data0;
@@ -220,3 +231,71 @@ parse_split_event_test() ->
ok.
-endif.
+
+-spec events([event()]) -> iolist().
+events(Events) ->
+ [event(Event) || Event <- Events].
+
+-spec event(event()) -> iolist().
+event(Event) ->
+ [
+ event_comment(Event),
+ event_id(Event),
+ event_name(Event),
+ event_data(Event),
+ event_retry(Event),
+ $\n
+ ].
+
+event_comment(#{comment := Comment}) ->
+ prefix_lines(Comment, <<>>);
+event_comment(_) ->
+ [].
+
+event_id(#{id := ID}) ->
+ nomatch = binary:match(iolist_to_binary(ID), <<"\n">>),
+ [<<"id: ">>, ID, $\n];
+event_id(_) ->
+ [].
+
+event_name(#{event := Name0}) ->
+ Name = if
+ is_atom(Name0) -> atom_to_binary(Name0, utf8);
+ true -> iolist_to_binary(Name0)
+ end,
+ nomatch = binary:match(Name, <<"\n">>),
+ [<<"event: ">>, Name, $\n];
+event_name(_) ->
+ [].
+
+event_data(#{data := Data}) ->
+ prefix_lines(Data, <<"data">>);
+event_data(_) ->
+ [].
+
+event_retry(#{retry := Retry}) ->
+ [<<"retry: ">>, integer_to_binary(Retry), $\n];
+event_retry(_) ->
+ [].
+
+prefix_lines(IoData, Prefix) ->
+ Lines = binary:split(iolist_to_binary(IoData), <<"\n">>, [global]),
+ [[Prefix, <<": ">>, Line, $\n] || Line <- Lines].
+
+-ifdef(TEST).
+event_test() ->
+ _ = event(#{}),
+ _ = event(#{comment => "test"}),
+ _ = event(#{data => "test"}),
+ _ = event(#{data => "test\ntest\ntest"}),
+ _ = event(#{data => "test\ntest\ntest\n"}),
+ _ = event(#{data => <<"test\ntest\ntest">>}),
+ _ = event(#{data => [<<"test">>, $\n, <<"test">>, [$\n, "test"]]}),
+ _ = event(#{event => test}),
+ _ = event(#{event => "test"}),
+ _ = event(#{id => "test"}),
+ _ = event(#{retry => 5000}),
+ _ = event(#{event => "test", data => "test"}),
+ _ = event(#{id => "test", event => "test", data => "test"}),
+ ok.
+-endif.