{-# LANGUAGE OverloadedStrings #-} module System.ZMQ4.Endpoint ( parseAttoEndpoint , parseAttoTCPEndpoint , parseAttoUDPEndpoint , pTransport , pEndpoint , endpointAddr , endpointPort , endpointTransport , newEndpoint , newEndpointPort , newEndpointAddrInfo , newEndpointPortAddrInfo , newTCPEndpoint , newTCPEndpointAddrInfo , newUDPEndpoint , toAddrInfo , Port , Address , Transport(..) , Endpoint(..) ) where import Control.Applicative import Data.Attoparsec.ByteString.Char8 as A import Data.ByteString (ByteString) import Network.Socket (AddrInfo) import qualified Data.ByteString.Char8 as B import qualified Data.Char import qualified Network.Socket import qualified Network.SockAddr type Port = Int type Address = ByteString data Transport = TCP | UDP | IPC | InProc | PGM | EPGM deriving (Port -> Transport -> ShowS [Transport] -> ShowS Transport -> [Char] forall a. (Port -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a showList :: [Transport] -> ShowS $cshowList :: [Transport] -> ShowS show :: Transport -> [Char] $cshow :: Transport -> [Char] showsPrec :: Port -> Transport -> ShowS $cshowsPrec :: Port -> Transport -> ShowS Show, Transport -> Transport -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Transport -> Transport -> Bool $c/= :: Transport -> Transport -> Bool == :: Transport -> Transport -> Bool $c== :: Transport -> Transport -> Bool Eq, Eq Transport Transport -> Transport -> Bool Transport -> Transport -> Ordering Transport -> Transport -> Transport forall a. Eq a -> (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a min :: Transport -> Transport -> Transport $cmin :: Transport -> Transport -> Transport max :: Transport -> Transport -> Transport $cmax :: Transport -> Transport -> Transport >= :: Transport -> Transport -> Bool $c>= :: Transport -> Transport -> Bool > :: Transport -> Transport -> Bool $c> :: Transport -> Transport -> Bool <= :: Transport -> Transport -> Bool $c<= :: Transport -> Transport -> Bool < :: Transport -> Transport -> Bool $c< :: Transport -> Transport -> Bool compare :: Transport -> Transport -> Ordering $ccompare :: Transport -> Transport -> Ordering Ord) data Endpoint = Endpoint Transport Address (Maybe Port) deriving (Port -> Endpoint -> ShowS [Endpoint] -> ShowS Endpoint -> [Char] forall a. (Port -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a showList :: [Endpoint] -> ShowS $cshowList :: [Endpoint] -> ShowS show :: Endpoint -> [Char] $cshow :: Endpoint -> [Char] showsPrec :: Port -> Endpoint -> ShowS $cshowsPrec :: Port -> Endpoint -> ShowS Show, Endpoint -> Endpoint -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Endpoint -> Endpoint -> Bool $c/= :: Endpoint -> Endpoint -> Bool == :: Endpoint -> Endpoint -> Bool $c== :: Endpoint -> Endpoint -> Bool Eq, Eq Endpoint Endpoint -> Endpoint -> Bool Endpoint -> Endpoint -> Ordering Endpoint -> Endpoint -> Endpoint forall a. Eq a -> (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a min :: Endpoint -> Endpoint -> Endpoint $cmin :: Endpoint -> Endpoint -> Endpoint max :: Endpoint -> Endpoint -> Endpoint $cmax :: Endpoint -> Endpoint -> Endpoint >= :: Endpoint -> Endpoint -> Bool $c>= :: Endpoint -> Endpoint -> Bool > :: Endpoint -> Endpoint -> Bool $c> :: Endpoint -> Endpoint -> Bool <= :: Endpoint -> Endpoint -> Bool $c<= :: Endpoint -> Endpoint -> Bool < :: Endpoint -> Endpoint -> Bool $c< :: Endpoint -> Endpoint -> Bool compare :: Endpoint -> Endpoint -> Ordering $ccompare :: Endpoint -> Endpoint -> Ordering Ord) pTransport :: Show a => a -> ByteString pTransport :: forall a. Show a => a -> ByteString pTransport a x = [Char] -> ByteString B.pack forall a b. (a -> b) -> a -> b $ forall a b. (a -> b) -> [a] -> [b] map Char -> Char Data.Char.toLower forall a b. (a -> b) -> a -> b $ forall a. Show a => a -> [Char] show a x pEndpoint :: Endpoint -> ByteString pEndpoint :: Endpoint -> ByteString pEndpoint (Endpoint Transport t ByteString a Maybe Port Nothing) = [ByteString] -> ByteString B.concat [forall a. Show a => a -> ByteString pTransport Transport t, ByteString "://" , ByteString a] pEndpoint (Endpoint Transport t ByteString a (Just Port p)) = [ByteString] -> ByteString B.concat [forall a. Show a => a -> ByteString pTransport Transport t, ByteString "://" , ByteString a, ByteString ":", [Char] -> ByteString B.pack forall a b. (a -> b) -> a -> b $ forall a. Show a => a -> [Char] show Port p] newEndpoint :: Transport -> Address -> Endpoint newEndpoint :: Transport -> ByteString -> Endpoint newEndpoint Transport transport ByteString addr = Transport -> ByteString -> Maybe Port -> Endpoint newEndpointPort' Transport transport ByteString addr forall a. Maybe a Nothing newEndpointAddrInfo :: Transport -> AddrInfo -> Endpoint newEndpointAddrInfo :: Transport -> AddrInfo -> Endpoint newEndpointAddrInfo Transport transport AddrInfo addr = Transport -> AddrInfo -> Maybe Port -> Endpoint newEndpointPortAddrInfo' Transport transport AddrInfo addr forall a. Maybe a Nothing newEndpointPort' :: Transport -> Address -> Maybe Port -> Endpoint newEndpointPort' :: Transport -> ByteString -> Maybe Port -> Endpoint newEndpointPort' Transport transport ByteString addr Maybe Port port = Transport -> ByteString -> Maybe Port -> Endpoint Endpoint Transport transport ByteString addr Maybe Port port newEndpointPortAddrInfo' :: Transport -> AddrInfo -> Maybe Port -> Endpoint newEndpointPortAddrInfo' :: Transport -> AddrInfo -> Maybe Port -> Endpoint newEndpointPortAddrInfo' Transport transport AddrInfo addr Maybe Port port = Transport -> ByteString -> Maybe Port -> Endpoint newEndpointPort' Transport transport (SockAddr -> ByteString Network.SockAddr.showSockAddrBS forall a b. (a -> b) -> a -> b $ AddrInfo -> SockAddr Network.Socket.addrAddress AddrInfo addr) Maybe Port port newEndpointPort :: Transport -> Address -> Port -> Endpoint newEndpointPort :: Transport -> ByteString -> Port -> Endpoint newEndpointPort Transport transport ByteString addr Port port = Transport -> ByteString -> Maybe Port -> Endpoint newEndpointPort' Transport transport ByteString addr (forall a. a -> Maybe a Just Port port) newEndpointPortAddrInfo :: Transport -> AddrInfo -> Port -> Endpoint newEndpointPortAddrInfo :: Transport -> AddrInfo -> Port -> Endpoint newEndpointPortAddrInfo Transport transport AddrInfo addr Port port = Transport -> AddrInfo -> Maybe Port -> Endpoint newEndpointPortAddrInfo' Transport transport AddrInfo addr (forall a. a -> Maybe a Just Port port) newTCPEndpoint :: Address -> Port -> Endpoint newTCPEndpoint :: ByteString -> Port -> Endpoint newTCPEndpoint ByteString addr Port port = Transport -> ByteString -> Port -> Endpoint newEndpointPort Transport TCP ByteString addr Port port newUDPEndpoint :: Address -> Port -> Endpoint newUDPEndpoint :: ByteString -> Port -> Endpoint newUDPEndpoint ByteString addr Port port = Transport -> ByteString -> Port -> Endpoint newEndpointPort Transport UDP ByteString addr Port port newTCPEndpointAddrInfo :: AddrInfo -> Port -> Endpoint newTCPEndpointAddrInfo :: AddrInfo -> Port -> Endpoint newTCPEndpointAddrInfo AddrInfo addr Port port = Transport -> AddrInfo -> Port -> Endpoint newEndpointPortAddrInfo Transport TCP AddrInfo addr Port port toAddrInfo :: Endpoint -> IO [AddrInfo] toAddrInfo :: Endpoint -> IO [AddrInfo] toAddrInfo (Endpoint Transport _ ByteString a (Just Port p)) = Maybe AddrInfo -> Maybe [Char] -> Maybe [Char] -> IO [AddrInfo] Network.Socket.getAddrInfo forall a. Maybe a Nothing (forall a. a -> Maybe a Just forall a b. (a -> b) -> a -> b $ ByteString -> [Char] B.unpack ByteString a) (forall a. a -> Maybe a Just forall a b. (a -> b) -> a -> b $ forall a. Show a => a -> [Char] show Port p) toAddrInfo (Endpoint Transport _ ByteString a Maybe Port _) = Maybe AddrInfo -> Maybe [Char] -> Maybe [Char] -> IO [AddrInfo] Network.Socket.getAddrInfo forall a. Maybe a Nothing (forall a. a -> Maybe a Just forall a b. (a -> b) -> a -> b $ ByteString -> [Char] B.unpack ByteString a) forall a. Maybe a Nothing parseTransport :: Parser Transport parseTransport :: Parser Transport parseTransport = do ByteString t <- (Char -> Bool) -> Parser ByteString A.takeWhile (forall a. Eq a => a -> a -> Bool /=Char ':') ByteString _ <- ByteString -> Parser ByteString string ByteString "://" Transport r <- case ByteString t of ByteString "tcp" -> forall (f :: * -> *) a. Applicative f => a -> f a pure Transport TCP ByteString "udp" -> forall (f :: * -> *) a. Applicative f => a -> f a pure Transport UDP ByteString "ipc" -> forall (f :: * -> *) a. Applicative f => a -> f a pure Transport IPC ByteString "inproc" -> forall (f :: * -> *) a. Applicative f => a -> f a pure Transport InProc ByteString "pgm" -> forall (f :: * -> *) a. Applicative f => a -> f a pure Transport PGM ByteString "epgm" -> forall (f :: * -> *) a. Applicative f => a -> f a pure Transport EPGM ByteString _ -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a fail forall a b. (a -> b) -> a -> b $ [Char] "Unknown transport " forall a. [a] -> [a] -> [a] ++ (ByteString -> [Char] B.unpack ByteString t) forall (m :: * -> *) a. Monad m => a -> m a return Transport r parseAddress :: Parser Address parseAddress :: Parser ByteString parseAddress = (Char -> Bool) -> Parser ByteString A.takeWhile(forall a. Eq a => a -> a -> Bool /=Char ':') parsePort :: Parser Port parsePort :: Parser Port parsePort = do Char _ <- Char -> Parser Char char Char ':' Port d <- forall a. Integral a => Parser a decimal forall (m :: * -> *) a. Monad m => a -> m a return Port d parseEndpoint :: Parser Endpoint parseEndpoint :: Parser Endpoint parseEndpoint = Transport -> ByteString -> Maybe Port -> Endpoint Endpoint forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Parser Transport parseTransport forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Parser ByteString parseAddress forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional Parser Port parsePort parseTCPEndpoint :: Parser Endpoint parseTCPEndpoint :: Parser Endpoint parseTCPEndpoint = Transport -> ByteString -> Maybe Port -> Endpoint Endpoint forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall (f :: * -> *) a. Applicative f => a -> f a pure Transport TCP forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Parser ByteString parseAddress forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional Parser Port parsePort parseUDPEndpoint :: Parser Endpoint parseUDPEndpoint :: Parser Endpoint parseUDPEndpoint = Transport -> ByteString -> Maybe Port -> Endpoint Endpoint forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall (f :: * -> *) a. Applicative f => a -> f a pure Transport UDP forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Parser ByteString parseAddress forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a) optional Parser Port parsePort parseAttoEndpoint :: ByteString -> Either String Endpoint parseAttoEndpoint :: ByteString -> Either [Char] Endpoint parseAttoEndpoint = forall a. Parser a -> ByteString -> Either [Char] a A.parseOnly Parser Endpoint parseEndpoint parseAttoTCPEndpoint :: ByteString -> Either String Endpoint parseAttoTCPEndpoint :: ByteString -> Either [Char] Endpoint parseAttoTCPEndpoint = forall a. Parser a -> ByteString -> Either [Char] a A.parseOnly Parser Endpoint parseTCPEndpoint parseAttoUDPEndpoint :: ByteString -> Either String Endpoint parseAttoUDPEndpoint :: ByteString -> Either [Char] Endpoint parseAttoUDPEndpoint = forall a. Parser a -> ByteString -> Either [Char] a A.parseOnly Parser Endpoint parseUDPEndpoint endpointAddr :: Endpoint -> Address endpointAddr :: Endpoint -> ByteString endpointAddr (Endpoint Transport _ ByteString a Maybe Port _) = ByteString a endpointPort :: Endpoint -> Maybe Port endpointPort :: Endpoint -> Maybe Port endpointPort (Endpoint Transport _ ByteString _ Maybe Port p) = Maybe Port p endpointTransport :: Endpoint -> Transport endpointTransport :: Endpoint -> Transport endpointTransport (Endpoint Transport t ByteString _ Maybe Port _) = Transport t