{-# LANGUAGE ScopedTypeVariables #-} module Network.N2O.Protocols.Nitro where import Control.Monad (forM_) import qualified Data.Map.Strict as M import qualified Data.ByteString.Lazy as L import qualified Data.ByteString as BS import qualified Data.Binary as B import qualified Data.ByteString.Lazy.Char8 as CL8 import Data.IORef import Data.BERT import Network.N2O.Core import Network.N2O.Types as Types import Network.N2O.Nitro import Network.N2O.Protocols.Types as Proto nitroProto :: (Show a, B.Binary a) => Proto N2OProto a nitroProto = Proto { protoInfo = nitroInfo } nitroInfo :: (Show a, B.Binary a) => N2OProto a -> N2O N2OProto a (Result (N2OProto a)) nitroInfo message = do ref <- ask cx@Context {cxHandler = handle, cxDePickle = dePickle} <- lift $ readIORef ref lift $ putStrLn ("NITRO : " ++ show message) case message of msg@(N2ONitro (Proto.Init pid)) -> do handle Types.Init actions <- getActions rendered <- renderActions' actions return $ Reply (reply rendered) msg@(N2ONitro (Pickle _source pickled linked)) -> do forM_ (M.toList linked) (uncurry put) case dePickle pickled of Just x -> do handle (Message x) actions <- getActions rendered <- renderActions' actions return $ Reply (reply rendered) _ -> return Unknown msg@(N2ONitro Done) -> do handle Terminate return Empty where reply bs = Io bs L.empty renderActions' actions = case actions of [] -> return L.empty actions -> do putActions [] first <- renderActions actions actions2 <- getActions second <- renderActions actions2 putActions [] return $ first <> CL8.pack ";" <> second