Skip to content

Instantly share code, notes, and snippets.

@Chadtech
Created March 23, 2018 01:19
Show Gist options
  • Save Chadtech/59d10d2c34298cc8566d12f936d61da3 to your computer and use it in GitHub Desktop.
Save Chadtech/59d10d2c34298cc8566d12f936d61da3 to your computer and use it in GitHub Desktop.
-- Ports.Manager --
type alias Manager msg =
{ threads : Dict String (Decoder msg)
, seed : Random.Seed
, errCtor : Error -> msg
}
type Error
= IdDecoderFailed String
| ThreadDoesNotExist
| MsgDecoderFailed String
init : Random.Seed -> (String -> msg) -> Manager msg
init seed errCtor =
{ threads = Dict.empty
, seed = seed
, errCtor = errCtor
}
type alias Request a msg =
{ decoder : Decoder a
, msgCtor : a -> msg
, outgoingMsg : (String, Encode.Value)
}
request : Decoder a -> (a -> msg)-> (String, Encode.Value) -> Request
request =
Request
jsonRequest : (Decode.Value -> msg) -> (String, Encode.Value) -> Request
jsonRequest =
Request Decode.value
map : (a -> b) -> Request a -> Request b
map ctor request =
{ request | msgCtor = ctor << request.msgCtor }
update : Request a msg -> Manager msg -> (Manager msg, Cmd msg)
update request manager =
let
(id, newSeed) =
Random.step idGenerator manager.seed
in
( { manager
| threads =
Dict.set
id
(Decode.map request.msgCtor request.decoder)
manager.threads
, seed = newSeed
}
, encode id (manager.bundler request.jsMsg)
)
encode : String -> (String, Encode.Value) -> Encode.Value
encode id (type, payload) =
[ ("id", Encode.string id)
, ("type", Encode.string type)
, ("payload", payload)
]
|> Encode.object
decode : Manager msg -> Decode.Value -> msg
decode manager json =
case Decode.decodeValue (Decode.field "id" Decode.string) json of
Ok id ->
case Dict.get id manager.threads of
Just decoder ->
case Decode.decodeValue decoder json of
Ok msg ->
msg
Err err ->
err
|> MsgDecoderFailed
|> manager.errCtor
Nothing ->
manager.errCtor ThreadDoesNotExist
Err err ->
err
|> IdDecoderFailed
|> manager.errCtor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment