Skip to content

Instantly share code, notes, and snippets.

@max630
Created May 26, 2012 07:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save max630/2792677 to your computer and use it in GitHub Desktop.
Save max630/2792677 to your computer and use it in GitHub Desktop.
Enumerator-based IO Frontend for JSON-RPC
module IOFrontend where
import qualified Control.Monad.IO.Class as MIO
import qualified Data.Aeson as A
import qualified Data.Attoparsec as AP
import qualified Data.ByteString.Lazy as BSL
import qualified Data.Enumerator as E
import qualified Data.Enumerator.Binary as EB
import qualified Data.Enumerator.List as EL
import qualified GHC.IO.Handle as GIO
import qualified GHC.IO.Handle.FD as GIOF
import Data.Attoparsec.Enumerator (iterParser)
mkHandler :: MIO.MonadIO m => GIO.Handle -> GIO.Handle -> ((A.Value -> m ()) -> m (), A.Value -> m (), m ())
mkHandler input output = (handle, send, close)
where
handle dispatch =
E.run_ (EB.enumHandle 10240 input
E.$$ (E.sequence (iterParser jsonOrEOF)
E.=$ EL.isolateWhile isRight
E.=$ EL.map (\(Right v) -> v)
E.=$ EL.mapM_ dispatch))
send value = MIO.liftIO $ BSL.hPut output $ A.encode value
close = MIO.liftIO $ GIO.hClose output
isRight (Left _) = False
isRight (Right _) = True
jsonOrEOF = AP.takeWhile (AP.inClass " \t\r\n") >> AP.eitherP (AP.try AP.endOfInput) A.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment