metro-socket-0.1.0.0: src/Metro/SocketServer.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Metro.SocketServer
( SocketServer
, socketServer
, SSSID (..)
) where
import Data.List (isPrefixOf)
import Metro.Class (Servable (..), Transport (..),
TransportConfig)
import Metro.TCPServer
import qualified Metro.TP.Socket as T (Socket, mapTCPSocket, mapUDPSocket)
import Metro.UDPServer
import Network.Socket (SockAddr, Socket)
data SocketServer = TCP TCPServer
| UDP UDPServer
data SSSID = TCPSID Socket
| UDPSID SockAddr
instance Servable SocketServer where
data ServerConfig SocketServer = SSConfig String
type SID SocketServer = SSSID
type STP SocketServer = T.Socket
newServer (SSConfig hostPort) =
if "udp" `isPrefixOf` hostPort then UDP <$> newServer (udpServer hostPort)
else TCP <$> newServer (tcpServer hostPort)
servOnce (TCP s) done = servOnce s $ mapTCPServOnceDone done
servOnce (UDP s) done = servOnce s $ mapUDPServOnceDone done
onConnEnter (TCP s) (TCPSID sid) = onConnEnter s sid
onConnEnter (UDP s) (UDPSID sid) = onConnEnter s sid
onConnEnter _ _ = error "onConnEnter invalid type"
onConnLeave (TCP s) (TCPSID sid) = onConnLeave s sid
onConnLeave (UDP s) (UDPSID sid) = onConnLeave s sid
onConnLeave _ _ = error "onConnLeave invalid type"
servClose (TCP s) = servClose s
servClose (UDP s) = servClose s
mapTCPServOnceDone
:: (Maybe (SID SocketServer, TransportConfig (STP SocketServer)) -> m ())
-> Maybe (SID TCPServer, TransportConfig (STP TCPServer)) -> m ()
mapTCPServOnceDone done Nothing = done Nothing
mapTCPServOnceDone done (Just (sid, stp)) = done (Just (TCPSID sid, T.mapTCPSocket stp))
mapUDPServOnceDone
:: (Maybe (SID SocketServer, TransportConfig (STP SocketServer)) -> m ())
-> Maybe (SID UDPServer, TransportConfig (STP UDPServer)) -> m ()
mapUDPServOnceDone done Nothing = done Nothing
mapUDPServOnceDone done (Just (sid, stp)) = done (Just (UDPSID sid, T.mapUDPSocket stp))
socketServer :: String -> ServerConfig SocketServer
socketServer = SSConfig