{-# LANGUAGE FlexibleContexts #-} module Network.Wai.Trans ( -- * Application ApplicationT , liftApplication , runApplicationT -- * Middleware , MiddlewareT , liftMiddleware , runMiddlewareT ) where import Control.Monad.Base import Control.Monad.Trans.Control.Identity import Network.Wai -- | A type synonym for a wai 'Application' which has been lifted from the 'IO' monad. type ApplicationT m = Request -> (Response -> m ResponseReceived) -> m ResponseReceived -- | Lift a wai 'Application' to an 'ApplicationT'. liftApplication :: MonadBaseControlIdentity IO m => Application -> ApplicationT m liftApplication app request respond = liftBaseWithIdentity $ \ runInBase -> app request $ runInBase . respond -- | Run an 'ApplicationT' in the inner monad. runApplicationT :: MonadBaseControlIdentity IO m => ApplicationT m -> m Application runApplicationT appT = liftBaseWithIdentity $ \ runInBase -> return $ \ request respond -> runInBase $ appT request $ liftBase . respond -- | A type synonym for a wai 'Middleware' which has been lifted from the 'IO' monad. type MiddlewareT m = ApplicationT m -> ApplicationT m -- | Lift a wai 'Middleware' to a 'MiddlewareT'. liftMiddleware :: MonadBaseControlIdentity IO m => Middleware -> MiddlewareT m liftMiddleware mid appT request respond = do app <- runApplicationT appT liftBaseWithIdentity $ \ runInBase -> mid app request $ runInBase . respond -- | Run a 'MiddlewareT' in the inner monad. runMiddlewareT :: MonadBaseControlIdentity IO m => MiddlewareT m -> m Middleware runMiddlewareT midT = liftBaseWithIdentity $ \ runInBase -> return $ \ app request respond -> do app' <- runInBase . runApplicationT . midT $ liftApplication app app' request respond