module Network.Wai.REST
( RESTController
, index, show, create, update, delete
, edit, new
) where
import Prelude hiding (show)
import Control.Monad.State
import Data.Conduit
import Network.Wai.Responses
import Network.Wai.Router
import Network.HTTP.Types
data RESTControllerState = RESTControllerState
{ restIndex :: Route ()
, restShow :: Route ()
, restCreate :: Route ()
, restUpdate :: Route ()
, restDelete :: Route ()
, restEdit :: Route ()
, restNew :: Route ()
}
defaultRESTControllerState :: RESTControllerState
defaultRESTControllerState = RESTControllerState
{ restIndex = routeAll $ notFound
, restShow = routeAll $ notFound
, restCreate = routeAll $ notFound
, restUpdate = routeAll $ notFound
, restDelete = routeAll $ notFound
, restEdit = routeAll $ notFound
, restNew = routeAll $ notFound
}
instance Routeable RESTControllerState where
runRoute controller = runRoute $ do
routeMethod GET $ do
routeTop $ restIndex controller
routeName "new" $ restNew controller
routeVar "id" $ do
routeTop $ restShow controller
routeName "edit" $ restEdit controller
routeMethod POST $ routeTop $ restCreate controller
routeMethod PUT $ routeVar "id" $ restUpdate controller
routeMethod DELETE $ routeVar "id" $ restDelete controller
type RESTController a = StateT RESTControllerState (ResourceT IO) a
instance Routeable (RESTController a) where
runRoute controller = rt
where rt req = do
(_, st) <- runStateT controller defaultRESTControllerState
runRoute st req
index :: Routeable r => r -> RESTController ()
index route = modify $ \controller ->
controller { restIndex = routeAll route }
create :: Routeable r => r -> RESTController ()
create route = modify $ \controller ->
controller { restCreate = routeAll route }
edit :: Routeable r => r -> RESTController ()
edit route = modify $ \controller ->
controller { restEdit = routeAll route }
new :: Routeable r => r -> RESTController ()
new route = modify $ \controller ->
controller { restNew = routeAll route }
show :: Routeable r => r -> RESTController ()
show route = modify $ \controller ->
controller { restShow = routeAll route }
update :: Routeable r => r -> RESTController ()
update route = modify $ \controller ->
controller { restUpdate = routeAll route }
delete :: Routeable r => r -> RESTController ()
delete route = modify $ \controller ->
controller { restDelete = routeAll route }