{-# LANGUAGE KindSignatures #-}
module Network.N2O.Types where
import qualified Data.Binary as B
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import Data.IORef
import Data.Map.Strict (Map, (!?), insert)
import qualified Data.Text.Lazy as TL
type Header = (BS.ByteString, BS.ByteString)
data Req = Req
{ reqPath :: BS.ByteString
, reqMeth :: BS.ByteString
, reqVers :: BS.ByteString
, reqHead :: [Header]
}
data Context (f :: * -> *) a = Context
{ cxHandler :: Event a -> N2O f a (Result a)
, cxReq :: Req
, cxMiddleware :: [Context f a -> Context f a]
, cxProtos :: [Proto f a]
, cxDePickle :: BL.ByteString -> Maybe a
, cxPickle :: a -> BL.ByteString
, cxState :: Map BS.ByteString BL.ByteString
}
data Result a
= Reply a
| Ok
| Unknown
| Empty
deriving (Show, Eq)
newtype Proto f a = Proto
{ protoInfo :: f a -> N2O f a (Result (f a))
}
data Event a
= Init
| Message a
| Terminate
type State f a = IORef (Context f a)
type N2O f a = N2OT (State f a) IO
newtype N2OT state m a = N2OT
{ runN2O :: state -> m a
}
instance Functor m => Functor (N2OT state m) where
fmap f (N2OT g) = N2OT (fmap f . g)
instance Applicative m => Applicative (N2OT state m) where
pure = N2OT . const . pure
(N2OT f) <*> (N2OT g) = N2OT $ \state -> f state <*> g state
instance Monad m => Monad (N2OT state m) where
m >>= k =
N2OT $ \state -> do
a <- runN2O m state
runN2O (k a) state