packages feed

socketed-0.1.0.0: Network/Socketed/Internal.hs

{-# LANGUAGE ScopedTypeVariables #-}

module Network.Socketed.Internal where

import Conduit (
      ConduitM, MonadIO,
      (.|), runConduit, sourceHandle, stdoutC, await, yield, leftover
   )

import Control.Concurrent (threadDelay)
import Control.Concurrent.Async (Async, async, cancel, race, wait)
import Control.Exception (AsyncException(..), catch)

import Data.ByteString (ByteString, empty)
import Data.Either.Utils (fromRight)
import qualified Data.Conduit.Binary as CB (lines)

import Language.Haskell.TH (stringE)
import Language.Haskell.TH.Quote (QuasiQuoter(..))

import System.IO (stdin)

data SocketedOptions = SocketedOptions {
      host :: String,
      port :: Int
   }

stdinLines :: MonadIO m => ConduitM a ByteString m ()
stdinLines = sourceHandle stdin .| CB.lines

takeUntil2Empty :: MonadIO m => ConduitM ByteString ByteString m ()
takeUntil2Empty =
      loop
   where
      loop = do
         a <- await
         b <- await
         case (a, b) of
            (Nothing, Nothing) -> loop
            (Just x, Nothing) -> leftover x >> loop
            (Nothing, Just x) -> leftover x >> loop
            (Just x, Just y)
               | x == empty && y == empty -> return ()
               | otherwise -> leftover y >> yield x >> loop

stdinPassthrough :: IO ()
stdinPassthrough = runConduit $ sourceHandle stdin .| stdoutC

withStdinPassthrough :: IO a -> IO a
withStdinPassthrough work = do
   a <- async work
   stdinPassthrough
   wait a

showWSHost :: String -> Int -> String
showWSHost h p = "ws://" ++ h ++ ":" ++ show p

stringQuote :: QuasiQuoter
stringQuote = QuasiQuoter {
   quoteExp = stringE,
   quotePat = undefined,
   quoteType = undefined,
   quoteDec = undefined
}

waitTimeout :: forall a . Async a -> a -> Int -> IO a
waitTimeout task def time =
   let
      left = threadDelay time >> cancel task
      right = wait task
      hdl :: AsyncException -> IO a
      hdl _ = return def
   in
      fmap fromRight (race left right) `catch` hdl