wai-middleware-verbs 0.0.4 → 0.0.5
raw patch · 2 files changed
+77/−31 lines, 2 filesdep +exceptionsdep +monad-loggerdep +resourcetdep ~basedep ~wai-transformersPVP ok
version bump matches the API change (PVP)
Dependencies added: exceptions, monad-logger, resourcet, transformers-base
Dependency ranges changed: base, wai-transformers
API changes (from Hackage documentation)
+ Network.Wai.Middleware.Verbs: instance (Control.Monad.Trans.Resource.Internal.MonadResource m, Control.Monad.Base.MonadBase GHC.Types.IO m) => Control.Monad.Trans.Resource.Internal.MonadResource (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Error.Class.MonadError e' m => Control.Monad.Error.Class.MonadError e' (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Logger.MonadLogger m => Control.Monad.Logger.MonadLogger (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance GHC.Base.MonadPlus m => GHC.Base.Alternative (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
+ Network.Wai.Middleware.Verbs: instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Network.Wai.Middleware.Verbs.VerbListenerT r e u m)
Files
src/Network/Wai/Middleware/Verbs.hs view
@@ -1,25 +1,30 @@ {-# LANGUAGE- GeneralizedNewtypeDeriving+ TupleSections+ , FlexibleContexts+ , StandaloneDeriving , ScopedTypeVariables , MultiParamTypeClasses- , TupleSections+ , GeneralizedNewtypeDeriving #-} +{-|+Module : Network.Wai.Middleware.Verbs+Copyright : (c) Athan Clark, 2015+License : BSD-3+Maintainer : athan.clark@gmail.com+Stability : experimental+Portability : POSIX++This module provides everything you need to route based off different HTTP verbs.+The <#g:1 Combinators> section defines the @get@, @post@ and other functions you would+expect in a toolset like this. Likewise, we also include tools for manually+looking into the <#t:VerbListenerT VerbListenerT> object constructed from the combinators, and+turning it directly into a WAI @MiddlewareT@.+-}+ module Network.Wai.Middleware.Verbs- ( Verbs (..)- , Verb- , getVerb- , HandleUpload- , RespondUpload- , ResponseSpec- , supplyReq- , lookupVerb- , lookupVerbM- , VerbListenerT (..)- , execVerbListenerT- , mapVerbs- , verbsToMiddleware- , get+ ( -- * Combinators+ get , getReq , post , postReq@@ -27,6 +32,22 @@ , putReq , delete , deleteReq+ , -- * Types+ Verbs (..)+ , Verb+ , getVerb+ , ResponseSpec+ , HandleUpload+ , RespondUpload+ , supplyReq+ , -- ** Monad Transformer+ VerbListenerT (..)+ , execVerbListenerT+ , verbsToMiddleware+ , mapVerbs+ , -- * Utilities+ lookupVerb+ , lookupVerbM ) where @@ -38,27 +59,46 @@ import Data.Map (Map) import qualified Data.Map as Map import Data.Monoid+import Control.Applicative import Control.Monad.Trans import Control.Monad.Trans.Maybe import Control.Monad.State hiding (get, put) import qualified Control.Monad.State as S+import Control.Monad.Reader+import Control.Monad.Writer+import Control.Monad.Cont+import Control.Monad.Base+import Control.Monad.Catch+import Control.Monad.Trans.Resource import Control.Monad.Except+import Control.Monad.Logger import Control.Error --- * Verb Map+-- * Types +-- | Given a request, either throw a possibly existent error, or create some+-- upload result. type HandleUpload e m u = Request -> ExceptT (Maybe e) m u-type RespondUpload e u r = Request -> Either (Maybe e) u -> r++-- | Given a request and the potential result of handling an upload, return a+-- response (usually @Middleware@).+type RespondUpload e u r = Request -> Either (Maybe e) u -> r+ type ResponseSpec e u m r = (HandleUpload e m u, RespondUpload e u r) +-- | A map from an HTTP verb, to a responding and uploading mechanism. newtype Verbs e u m r = Verbs { unVerbs :: Map Verb (ResponseSpec e u m r) } deriving (Monoid) +instance Functor (Verbs e u m) where+ fmap f (Verbs xs) = Verbs $ (second (f .*)) <$> xs + type Verb = StdMethod +-- | Fetches the HTTP verb from the WAI @Request@ - defaults to GET. getVerb :: Request -> Verb getVerb req = fromMaybe GET $ httpMethodToMSym $ requestMethod req where@@ -67,17 +107,15 @@ | x == methodPost = Just POST | x == methodPut = Just PUT | x == methodDelete = Just DELETE- | otherwise = Nothing+ | otherwise = Nothing +-- | @flip ($)@ for supplying a @Request@ into the two @ResponseSpec@ functions. supplyReq :: Request -> Map Verb (ResponseSpec e u m r) -> Map Verb (ExceptT (Maybe e) m u, Either (Maybe e) u -> r) supplyReq req xs = bimap ($ req) ($ req) <$> xs -instance Functor (Verbs e u m) where- fmap f (Verbs xs) = Verbs $ (second (f .*)) <$> xs - -- | Take a verb map and a request, and return the lookup after providing the request -- (for upload cases). lookupVerb :: Verb@@ -86,7 +124,7 @@ -> Maybe (ExceptT (Maybe e) m u, Either (Maybe e) u -> r) lookupVerb v req vmap = Map.lookup v $ supplyReq req $ unVerbs vmap -+-- | Take the monadic partial result of @lookupVerb@, and actually handle the upload. lookupVerbM :: Monad m => Verb -> Request -> Verbs e u m r -> m (Maybe r) lookupVerbM v req vmap = runMaybeT $ do (uploadT, result) <- hoistMaybe $ lookupVerb v req vmap@@ -96,15 +134,19 @@ -- * Verb Writer +-- | The type variables are @r@ for the result, @e@ for the error type throwable+-- during uploading, @u@ is the sucessful upload type, and @m@ and @a@ form the+-- last two parts of the monad transformer. newtype VerbListenerT r e u m a = VerbListenerT { runVerbListenerT :: StateT (Verbs e u m r) m a }- deriving ( Functor- , Applicative- , Monad- , MonadState (Verbs e u m r)- , MonadIO+ deriving ( Functor, Applicative, Alternative, Monad, MonadFix, MonadPlus+ , MonadState (Verbs e u m r), MonadWriter w, MonadReader r, MonadIO+ , MonadError e', MonadCont, MonadBase b, MonadThrow, MonadCatch+ , MonadMask, MonadLogger ) +deriving instance (MonadResource m, MonadBase IO m) => MonadResource (VerbListenerT r e u m)+ execVerbListenerT :: Monad m => VerbListenerT r e u m a -> m (Verbs e u m r) execVerbListenerT xs = execStateT (runVerbListenerT xs) mempty @@ -113,7 +155,7 @@ lift ma = VerbListenerT $ lift ma -+-- | Turn a map from HTTP verbs to middleware, into a middleware. verbsToMiddleware :: MonadIO m => VerbListenerT (MiddlewareT m) e u m () -> MiddlewareT m
wai-middleware-verbs.cabal view
@@ -1,5 +1,5 @@ Name: wai-middleware-verbs-Version: 0.0.4+Version: 0.0.5 Author: Athan Clark <athan.clark@gmail.com> Maintainer: Athan Clark <athan.clark@gmail.com> License: BSD3@@ -19,12 +19,16 @@ , bifunctors , composition-extra >= 2.0.0 , containers+ , exceptions , errors , http-types+ , monad-logger , mtl+ , resourcet , transformers+ , transformers-base , wai- , wai-transformers+ , wai-transformers >= 0.0.3 Source-Repository head Type: git