module Web.REST
( REST(..), RESTController, rest, routeREST
, index, show, create, update, delete
, edit, new
) where
import Prelude hiding (show)
import Control.Monad
import Control.Monad.Trans.State
import Data.Functor.Identity
import Web.Simple.Responses
import Web.Simple.Controller
import Network.HTTP.Types
data REST r = REST
{ restIndex :: Controller r ()
, restShow :: Controller r ()
, restCreate :: Controller r ()
, restUpdate :: Controller r ()
, restDelete :: Controller r ()
, restEdit :: Controller r ()
, restNew :: Controller r ()
}
defaultREST :: REST r
defaultREST = REST
{ restIndex = respond $ notFound
, restShow = respond $ notFound
, restCreate = respond $ notFound
, restUpdate = respond $ notFound
, restDelete = respond $ notFound
, restEdit = respond $ notFound
, restNew = respond $ notFound
}
type RESTControllerM r a = StateT (REST r) Identity a
rest :: RESTControllerM r a -> REST r
rest rcontroller = snd . runIdentity $ runStateT rcontroller defaultREST
routeREST :: REST r -> Controller r ()
routeREST rst = do
routeMethod GET $ do
routeTop $ restIndex rst
routeName "new" $ restNew rst
routeVar "id" $ do
routeTop $ restShow rst
routeName "edit" $ restEdit rst
routeMethod POST $ routeTop $ restCreate rst
routeMethod DELETE $ routeVar "id" $ restDelete rst
routeMethod PUT $ routeVar "id" $ restUpdate rst
type RESTController r = RESTControllerM r ()
index :: Controller r a -> RESTController r
index route = modify $ \controller ->
controller { restIndex = void route }
create :: Controller r a -> RESTController r
create route = modify $ \controller ->
controller { restCreate = void route }
edit :: Controller r a -> RESTController r
edit route = modify $ \controller ->
controller { restEdit = void route }
new :: Controller r a -> RESTController r
new route = modify $ \controller ->
controller { restNew = void route }
show :: Controller r a -> RESTController r
show route = modify $ \controller ->
controller { restShow = void route }
update :: Controller r a -> RESTController r
update route = modify $ \controller ->
controller { restUpdate = void route }
delete :: Controller r a -> RESTController r
delete route = modify $ \controller ->
controller { restDelete = void route }