{-# LANGUAGE ExplicitNamespaces #-}
module TsWeb.Routing
( RoutingM
, runroute
, path
, dbwrite
, getpost
, get
, post
) where
import TsWeb.Types (Context(..), TsActionCtxT, TsSpockCtxT)
import TsWeb.Types.Db (ReadOnlyPool, ReadWritePool)
import qualified SuperRecord as SR
import qualified Web.Spock as Spock
import qualified Web.Spock.Routing
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Reader (ReaderT(..), ask, mapReaderT)
import Data.HVect (HVect(..), HVectElim, HasRep)
import GHC.TypeLits (type (-), KnownNat, KnownSymbol)
import SuperRecord ((:=)(..), FldProxy, Rec, Record, Sort, (&), rnil)
import Web.Routing.Combinators (PathState(Open))
import Web.Spock (Path)
import Web.Spock.Routing (withPrehook)
type RoutingM as lts xs sess
= ReaderT (Path as 'Open, ReadWritePool) (TsSpockCtxT lts xs sess)
runroute ::
(Applicative f, MonadIO m, Web.Spock.Routing.RouteM t)
=> ReadOnlyPool
-> ReadWritePool
-> ((ReadWritePool, Rec '[], f ()) -> ( ReadWritePool
, Rec lts
, t (Context lts '[ ReadOnlyPool]) m ()))
-> t ctx m ()
runroute ropool rwpool fn =
let (_p, r, m) = fn (rwpool, rnil, pure ())
in Spock.prehook (pure $ Context r (ropool :&: HNil)) m
path ::
( KnownNat ((SR.RecSize (Sort (l := (Path as 'Open) : lts)) - SR.RecTyIdxH 0 l (Sort (l := (Path as 'Open) : lts))) - 1)
, SR.RecCopy lts lts (Sort (l := (Path as 'Open) : lts))
, KnownNat (SR.RecSize lts)
, SR.KeyDoesNotExist l lts
, KnownSymbol l
)
=> FldProxy l
-> (Path as 'Open)
-> RoutingM as lts0 xs sess a
-> (ReadWritePool, Rec lts, (TsSpockCtxT lts0 xs sess) a)
-> ( ReadWritePool
, Record (l := (Path as 'Open) : lts)
, (TsSpockCtxT lts0 xs sess) a)
path l t m (pool, r, m0) = (pool, l := t & r, m0 >> runReaderT m (t, pool))
dbwrite ::
RoutingM as lts (ReadWritePool ': xs) sess () -> RoutingM as lts xs sess ()
dbwrite action = do
(_path, pool) <- ask
xform pool action
where
xform ::
nn -> RoutingM as lts (nn ': xs) sess () -> RoutingM as lts xs sess ()
xform nn = mapReaderT (xform' nn)
xform' ::
nn -> TsSpockCtxT lts (nn ': xs) sess () -> TsSpockCtxT lts xs sess ()
xform' nn = withPrehook (xform'' nn)
xform'' :: nn -> TsActionCtxT lts xs sess (Context lts (nn ': xs))
xform'' nn = do
ctx <- Spock.getContext
pure $ ctx {ctxExtras = nn :&: ctxExtras ctx}
getpost ::
Data.HVect.HasRep as
=> Data.HVect.HVectElim as (TsActionCtxT lts xs sess ())
-> RoutingM as lts xs sess ()
getpost action = do
(p, _) <- ask
lift $ Spock.getpost p action
get ::
Data.HVect.HasRep as
=> Data.HVect.HVectElim as (TsActionCtxT lts xs sess ())
-> RoutingM as lts xs sess ()
get action = do
(p, _) <- ask
lift $ Spock.get p action
post ::
Data.HVect.HasRep as
=> Data.HVect.HVectElim as (TsActionCtxT lts xs sess ())
-> RoutingM as lts xs sess ()
post action = do
(p, _) <- ask
lift $ Spock.post p action