{-# LANGUAGE TupleSections #-} ------------------------------------------------------------------------------ module Snap.Snaplet.Rest.Resource.Builder ( addMedia , setCreate , setRead , setUpdate , setDelete , setToDiff , setFromParams , setPutAction ) where ------------------------------------------------------------------------------ import Control.Monad import Data.Maybe ------------------------------------------------------------------------------ import Snap.Core (Params) ------------------------------------------------------------------------------ import Snap.Snaplet.Rest.Resource.Internal import Snap.Snaplet.Rest.Resource.Media (Media (..)) ------------------------------------------------------------------------------ type ResourceBuilder res m id diff = Resource res m id diff -> Resource res m id diff ------------------------------------------------------------------------------ -- | Add a media representation for rendering and parsing. addMedia :: Monad m => Media res m diff int -> ResourceBuilder res m id diff addMedia media res = res { renderers = renderers res ++ renderers' , parsers = parsers res ++ parsers' , diffParsers = diffParsers res ++ diffParsers' , listRenderers = listRenderers res ++ listRenderers' , listParsers = listParsers res ++ listParsers' } where renderers' = fromMaybe [] $ do fromResource' <- _fromResource media (mts, render) <- responseMedia media return $ map (, fromResource' >=> render) mts parsers' = fromMaybe [] $ do toResource' <- _toResource media (mts, parse) <- requestMedia media return $ map (, parse >=> maybe (return Nothing) toResource') mts diffParsers' = fromMaybe [] $ do toDiff' <- _toDiff media (mts, parse) <- requestMedia media return $ map (, parse >=> maybe (return Nothing) toDiff') mts listRenderers' = fromMaybe [] $ do fromResourceList' <- _fromResourceList media (mts, render) <- responseMedia media return $ map (, fromResourceList' >=> render) mts listParsers' = fromMaybe [] $ do toResourceList' <- _toResourceList media (mts, parse) <- requestMedia media return $ map (, parse >=> maybe (return Nothing) toResourceList') mts ------------------------------------------------------------------------------ -- | Set the create method for the resource. setCreate :: (res -> m ()) -> ResourceBuilder res m id diff setCreate f res = res { create = Just f } ------------------------------------------------------------------------------ -- | Set the read method for the resource. setRead :: (id -> m [res]) -> ResourceBuilder res m id diff setRead f res = res { retrieve = Just f } ------------------------------------------------------------------------------ -- | Set the update method for the resource. The method must return -- a boolean, indicating whether anything was updated. setUpdate :: (id -> diff -> m Bool) -> ResourceBuilder res m id diff setUpdate f res = res { update = Just f } ------------------------------------------------------------------------------ -- | Set the delete method for the resource. The method must return a -- boolean, indicating whether anything was deleted. setDelete :: (id -> m Bool) -> ResourceBuilder res m id diff setDelete f res = res { delete = Just f } ------------------------------------------------------------------------------ -- | Sets the conversion function from resource to diff value. setToDiff :: (res -> diff) -> ResourceBuilder res m id diff setToDiff f res = res { toDiff = Just f } ------------------------------------------------------------------------------ -- | Sets the URL query string parser. setFromParams :: (Params -> Maybe id) -> ResourceBuilder res m id diff setFromParams f res = res { fromParams = Just f } ------------------------------------------------------------------------------ -- | Sets a specific action to take when a PUT method is received. If not -- set, this defaults to trying to update and then creating if that fails. setPutAction :: PutAction -> ResourceBuilder res m id diff setPutAction a res = res { putAction = Just a }