You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
1.8 KiB
89 lines
1.8 KiB
module WsMessage exposing (Action(..), WsMessage, createSession, decode, msgDecoder, strToAction)
|
|
|
|
import Dict exposing (Dict)
|
|
import Json.Decode exposing (Decoder, andThen, decodeString, fail, field, map2, map3, string, succeed)
|
|
import Json.Encode as Enc
|
|
import Model exposing (Model)
|
|
import Participant as Participant exposing (Participant)
|
|
|
|
|
|
type Action
|
|
= Publish
|
|
| CreateSession
|
|
|
|
|
|
stringToAction : Dict String Action
|
|
stringToAction =
|
|
Dict.fromList
|
|
[ ( "Publish", Publish )
|
|
, ( "CreateSession", CreateSession )
|
|
]
|
|
|
|
|
|
actionToString : Action -> String
|
|
actionToString action =
|
|
Dict.filter
|
|
(\_ v -> v == action)
|
|
stringToAction
|
|
|> Dict.keys
|
|
|> List.head
|
|
|> Maybe.withDefault ""
|
|
|
|
|
|
strToAction : String -> Decoder Action
|
|
strToAction str =
|
|
case Dict.get str stringToAction of
|
|
Just val ->
|
|
succeed val
|
|
|
|
Nothing ->
|
|
fail ("invalid action '" ++ str ++ "'")
|
|
|
|
|
|
type alias WsMessage =
|
|
{ action : Action
|
|
, publisher : Participant
|
|
, payload : String
|
|
}
|
|
|
|
|
|
|
|
-- DECODERS
|
|
|
|
|
|
msgDecoder : Decoder WsMessage
|
|
msgDecoder =
|
|
map3 WsMessage
|
|
(field "action" string |> andThen strToAction)
|
|
(field "publisher" Participant.decoder)
|
|
(field "payload" string)
|
|
|
|
|
|
decode : String -> Maybe WsMessage
|
|
decode str =
|
|
case decodeString msgDecoder str of
|
|
Ok msg ->
|
|
Just msg
|
|
|
|
Err _ ->
|
|
Nothing
|
|
|
|
|
|
|
|
-- ENCODERS
|
|
|
|
|
|
createSession : Model -> String
|
|
createSession model =
|
|
Enc.object
|
|
[ ( "action", Enc.string (actionToString CreateSession) )
|
|
, ( "publisher"
|
|
, Enc.object
|
|
[ ( "id", Enc.string model.me.id )
|
|
, ( "name", Enc.string model.me.name )
|
|
]
|
|
)
|
|
, ( "payload", Enc.string "" )
|
|
]
|
|
|> Enc.encode 0
|