module Network.Monad.Transfer.IO where

import qualified Network.Monad.Transfer as Transfer
import qualified Network.Monad.Reader as Reader

import qualified Network.TCP as TCP
import Control.Monad.Trans.Reader (ReaderT, runReaderT, )
import Control.Monad.IO.Class (MonadIO, )

import Data.Monoid (Monoid, )


transfer :: (TCP.HStream body, Monoid body, MonadIO io) =>
   TCP.HandleStream body -> Transfer.T io body
transfer h =
   Transfer.Cons {
      Transfer.readLine   =         Transfer.liftIOAsync $ TCP.readLine h,
      Transfer.readBlock  = \n   -> Transfer.liftIOAsync $ TCP.readBlock h n,
      Transfer.writeBlock = \str -> Transfer.liftIOSync  $ TCP.writeBlock h str
   }

run :: (TCP.HStream body, Monoid body, MonadIO io) =>
   Reader.T body io a -> TCP.HandleStream body -> io a
run m h = runReaderT m $ transfer h