n2o-0.11.0: src/Network/N2O/Core.hs
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
{-|
Module : Network.N2O.Core
Description : Core functions
Copyright : (c) Marat Khafizov, 2018
License : BSD 3-Clause
Maintainer : xafizoff@gmail.com
Stability : experimental
Portability : not portable
Core functions
-}
module Network.N2O.Core (lift, ask, put, get, mkCx, mkReq, protoRun) where
import Data.IORef
import qualified Data.Map.Strict as M
import qualified Data.Binary as B
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import qualified Data.Text.Lazy as TL
import Control.Exception (SomeException)
import Network.N2O.Types
import Data.Map.Strict (insert, (!?))
-- | 'Context' constructor
mkCx = Context
{ cxReq = undefined
, cxHandler = undefined
, cxMiddleware = []
, cxDePickle = undefined
, cxPickle = undefined
, cxProtos = []
, cxState = M.empty
}
-- | 'Req' constructor
mkReq = Req { reqPath = "/", reqMeth = "GET", reqVers = "HTTP/1.1", reqHead = [] }
-- | NO-OP result
nop :: Result a
nop = Empty
-- | N2O protocol loop
protoRun :: f a -> [Proto f a] -> N2O f a (Result (f a))
protoRun = loop []
where
loop _ _ [] = return nop
loop acc msg (proto:protos) = do
res <- protoInfo proto msg
case res of
Unknown -> loop acc msg protos
Empty -> return Empty
Reply msg1 -> return $ Reply msg1
a -> loop (a : acc) msg protos
-- | Lift underlying monad to the N2O monad
lift :: m a -> N2OT state m a
lift m = N2OT (const m)
-- | Get current state (env)
ask :: (Monad m) => N2OT state m state
ask = N2OT return
getContext = do
ref <- ask
lift $ readIORef ref
-- | Put data to the local state
put :: (B.Binary bin) => BS.ByteString -> bin -> N2O f a ()
put k v = do
state <- ask
lift $ modifyIORef state (\cx@Context{cxState=m} -> cx{cxState=insert k (B.encode v) m})
-- | Get data from the local state
get :: (B.Binary bin) => BS.ByteString -> N2O f a (Maybe bin)
get k = do
state <- N2OT return
cx <- lift $ readIORef state
let mp = cxState cx
case mp !? k of
Just v -> return $ Just (B.decode v)
_ -> return Nothing