diff options
author | Loïc Hoguin <[email protected]> | 2018-06-25 15:26:58 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2018-06-25 15:26:58 +0200 |
commit | 93b2b897cde238506c803faad4d1602d79dba7c9 (patch) | |
tree | 979cf936761447b13abdd251752cf8dd44877e0b | |
parent | af88cb78fc0dffb27fd9ab09659a6ba595493c1a (diff) | |
download | cowlib-93b2b897cde238506c803faad4d1602d79dba7c9.tar.gz cowlib-93b2b897cde238506c803faad4d1602d79dba7c9.tar.bz2 cowlib-93b2b897cde238506c803faad4d1602d79dba7c9.zip |
Add building of SSE events
-rw-r--r-- | src/cow_sse.erl | 83 |
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. |