wai-middleware-content-type 0.3.0 → 0.4.0
raw patch · 14 files changed
+185/−71 lines, 14 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Network.Wai.Middleware.ContentType.Types: 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.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance (GHC.Base.Monad m, Data.Url.MonadUrl b f m) => Data.Url.MonadUrl b f (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Logger.MonadLogger m => Control.Monad.Logger.MonadLogger (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Morph.MFunctor (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Reader.Class.MonadReader r' m => Control.Monad.Reader.Class.MonadReader r' (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Trans.Class.MonadTrans (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Trans.Control.MonadTransControl (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r)
- Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance GHC.Base.Functor m => GHC.Base.Functor (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Network.Wai.Middleware.ContentType.Types.FileExtMap r) (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance GHC.Base.Monad m => GHC.Base.Applicative (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance GHC.Base.Monad m => GHC.Base.Monad (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance GHC.Base.MonadPlus m => GHC.Base.Alternative (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Network.Wai.Middleware.ContentType.Types.FileExtListenerT r m)
- Network.Wai.Middleware.ContentType.Types: mapResponse :: Monad m => ((Status -> ResponseHeaders -> Response) -> Response) -> FileExtListenerT (Status -> ResponseHeaders -> Response) m a -> FileExtListenerT Response m a
+ Network.Wai.Middleware.ContentType.Types: ResponseVia :: !a -> !Status -> !ResponseHeaders -> !(a -> Status -> ResponseHeaders -> Response) -> ResponseVia
+ Network.Wai.Middleware.ContentType.Types: [responseData] :: ResponseVia -> !a
+ Network.Wai.Middleware.ContentType.Types: [responseFunction] :: ResponseVia -> !(a -> Status -> ResponseHeaders -> Response)
+ Network.Wai.Middleware.ContentType.Types: [responseHeaders] :: ResponseVia -> !ResponseHeaders
+ Network.Wai.Middleware.ContentType.Types: [responseStatus] :: ResponseVia -> !Status
+ Network.Wai.Middleware.ContentType.Types: data ResponseVia
+ Network.Wai.Middleware.ContentType.Types: 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.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance (GHC.Base.Monad m, Data.Url.MonadUrl b f m) => Data.Url.MonadUrl b f (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Logger.MonadLogger m => Control.Monad.Logger.MonadLogger (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Morph.MFunctor Network.Wai.Middleware.ContentType.Types.FileExtListenerT
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Reader.Class.MonadReader r' m => Control.Monad.Reader.Class.MonadReader r' (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Trans.Class.MonadTrans Network.Wai.Middleware.ContentType.Types.FileExtListenerT
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Trans.Control.MonadTransControl Network.Wai.Middleware.ContentType.Types.FileExtListenerT
+ Network.Wai.Middleware.ContentType.Types: instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance GHC.Base.Functor m => GHC.Base.Functor (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState Network.Wai.Middleware.ContentType.Types.FileExtMap (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance GHC.Base.Monad m => GHC.Base.Applicative (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance GHC.Base.Monad m => GHC.Base.Monad (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance GHC.Base.MonadPlus m => GHC.Base.Alternative (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Network.Wai.Middleware.ContentType.Types.FileExtListenerT m)
+ Network.Wai.Middleware.ContentType.Types: mapFileExtMap :: (Monad m) => (FileExtMap -> FileExtMap) -> FileExtListenerT m a -> FileExtListenerT m a
+ Network.Wai.Middleware.ContentType.Types: mapHeaders :: (ResponseHeaders -> ResponseHeaders) -> ResponseVia -> ResponseVia
+ Network.Wai.Middleware.ContentType.Types: mapStatus :: (Status -> Status) -> ResponseVia -> ResponseVia
+ Network.Wai.Middleware.ContentType.Types: overFileExts :: Monad m => [FileExt] -> (ResponseVia -> ResponseVia) -> FileExtListenerT m a -> FileExtListenerT m a
+ Network.Wai.Middleware.ContentType.Types: runResponseVia :: ResponseVia -> Response
- Network.Wai.Middleware.ContentType: fileExtsToMiddleware :: Monad m => FileExtListenerT Response m a -> MiddlewareT m
+ Network.Wai.Middleware.ContentType: fileExtsToMiddleware :: Monad m => FileExtListenerT m a -> MiddlewareT m
- Network.Wai.Middleware.ContentType: lookupFileExt :: Maybe AcceptHeader -> Maybe FileExt -> FileExtMap r -> Maybe r
+ Network.Wai.Middleware.ContentType: lookupFileExt :: Maybe AcceptHeader -> Maybe FileExt -> FileExtMap -> Maybe Response
- Network.Wai.Middleware.ContentType.Blaze: blaze :: Monad m => Html -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Blaze: blaze :: Monad m => Html -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.ByteString: bytestring :: Monad m => FileExt -> ByteString -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.ByteString: bytestring :: Monad m => FileExt -> ByteString -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Cassius: cassius :: Monad m => Css -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Cassius: cassius :: Monad m => Css -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Clay: clay :: Monad m => Config -> [App] -> Css -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Clay: clay :: Monad m => Config -> [App] -> Css -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Json: json :: (ToJSON j, Monad m) => j -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Json: json :: (ToJSON j, Monad m) => j -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Julius: julius :: Monad m => Javascript -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Julius: julius :: Monad m => Javascript -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Lucid: lucid :: Monad m => HtmlT m () -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Lucid: lucid :: Monad m => HtmlT m () -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Lucius: lucius :: Monad m => Css -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Lucius: lucius :: Monad m => Css -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Pandoc: markdown :: Monad m => Pandoc -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Pandoc: markdown :: Monad m => Pandoc -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Text: text :: Monad m => Text -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()
+ Network.Wai.Middleware.ContentType.Text: text :: Monad m => Text -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Types: FileExtListenerT :: StateT (FileExtMap r) m a -> FileExtListenerT r m a
+ Network.Wai.Middleware.ContentType.Types: FileExtListenerT :: StateT FileExtMap m a -> FileExtListenerT m a
- Network.Wai.Middleware.ContentType.Types: [runFileExtListenerT] :: FileExtListenerT r m a -> StateT (FileExtMap r) m a
+ Network.Wai.Middleware.ContentType.Types: [runFileExtListenerT] :: FileExtListenerT m a -> StateT FileExtMap m a
- Network.Wai.Middleware.ContentType.Types: execFileExtListenerT :: Monad m => FileExtListenerT r m a -> m (FileExtMap r)
+ Network.Wai.Middleware.ContentType.Types: execFileExtListenerT :: Monad m => FileExtListenerT m a -> m FileExtMap
- Network.Wai.Middleware.ContentType.Types: invalidEncoding :: Monad m => r -> FileExtListenerT r m ()
+ Network.Wai.Middleware.ContentType.Types: invalidEncoding :: Monad m => ResponseVia -> FileExtListenerT m ()
- Network.Wai.Middleware.ContentType.Types: newtype FileExtListenerT r m a
+ Network.Wai.Middleware.ContentType.Types: newtype FileExtListenerT m a
- Network.Wai.Middleware.ContentType.Types: type FileExtMap a = HashMap FileExt a
+ Network.Wai.Middleware.ContentType.Types: type FileExtMap = HashMap FileExt ResponseVia
Files
- src/Network/Wai/Middleware/ContentType.hs +8/−6
- src/Network/Wai/Middleware/ContentType/Blaze.hs +12/−3
- src/Network/Wai/Middleware/ContentType/ByteString.hs +8/−3
- src/Network/Wai/Middleware/ContentType/Cassius.hs +13/−3
- src/Network/Wai/Middleware/ContentType/Clay.hs +13/−3
- src/Network/Wai/Middleware/ContentType/Json.hs +8/−3
- src/Network/Wai/Middleware/ContentType/Julius.hs +13/−3
- src/Network/Wai/Middleware/ContentType/Lucid.hs +13/−4
- src/Network/Wai/Middleware/ContentType/Lucius.hs +13/−3
- src/Network/Wai/Middleware/ContentType/Pandoc.hs +13/−3
- src/Network/Wai/Middleware/ContentType/Text.hs +12/−3
- src/Network/Wai/Middleware/ContentType/Types.hs +55/−25
- test/Network/Wai/Middleware/ContentTypeSpec.hs +2/−2
- wai-middleware-content-type.cabal +2/−7
src/Network/Wai/Middleware/ContentType.hs view
@@ -53,11 +53,13 @@ -- a map of responses, find a response. lookupFileExt :: Maybe AcceptHeader -> Maybe FileExt- -> FileExtMap r- -> Maybe r-lookupFileExt mAcceptBS mFe fexts =- getFirst . foldMap (First . flip HM.lookup fexts) . findFE $- maybe allFileExts possibleFileExts mAcceptBS+ -> FileExtMap+ -> Maybe Response+lookupFileExt mAcceptBS mFe map =+ getFirst+ . foldMap (\fe -> First $ runResponseVia <$> HM.lookup fe map)+ . findFE+ $ maybe allFileExts possibleFileExts mAcceptBS where findFE :: [FileExt] -> [FileExt] findFE xs =@@ -65,7 +67,7 @@ Nothing -> xs Just fe -> fe <$ guard (fe `elem` xs) -fileExtsToMiddleware :: Monad m => FileExtListenerT Response m a -> MiddlewareT m+fileExtsToMiddleware :: Monad m => FileExtListenerT m a -> MiddlewareT m fileExtsToMiddleware xs app req respond = do map <- execFileExtListenerT xs let mAcceptHeader = lookup "Accept" (requestHeaders req)
src/Network/Wai/Middleware/ContentType/Blaze.hs view
@@ -1,7 +1,11 @@+{-# LANGUAGE+ OverloadedStrings+ #-}+ module Network.Wai.Middleware.ContentType.Blaze where import Network.Wai.Middleware.ContentType.Types-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response, responseBuilder) import qualified Text.Blaze.Html as H@@ -13,9 +17,14 @@ blaze :: Monad m => H.Html- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () blaze i =- tell' $ HM.singleton Html (blazeOnly i)+ tell' $ HM.singleton Html $+ ResponseVia+ i+ status200+ [("Content-Type", "text/html")]+ blazeOnly {-# INLINEABLE blaze #-}
src/Network/Wai/Middleware/ContentType/ByteString.hs view
@@ -1,7 +1,7 @@ module Network.Wai.Middleware.ContentType.ByteString where import Network.Wai.Middleware.ContentType.Types-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response, responseLBS) import qualified Data.ByteString.Lazy as LBS@@ -14,9 +14,14 @@ bytestring :: Monad m => FileExt -> LBS.ByteString- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () bytestring fe i =- tell' $ HM.singleton fe (bytestringOnly i)+ tell' $ HM.singleton fe $+ ResponseVia+ i+ status200+ []+ bytestringOnly {-# INLINEABLE bytestring #-}
src/Network/Wai/Middleware/ContentType/Cassius.hs view
@@ -1,8 +1,13 @@+{-# LANGUAGE+ OverloadedStrings+ #-}++ module Network.Wai.Middleware.ContentType.Cassius where import Network.Wai.Middleware.ContentType.Types as CT import Network.Wai.Middleware.ContentType.Text-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response) import Text.Cassius@@ -13,9 +18,14 @@ cassius :: Monad m => Css- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () cassius i =- tell' $ HM.singleton CT.Css (cassiusOnly i)+ tell' $ HM.singleton CT.Css $+ ResponseVia+ i+ status200+ [("Content-Type", "text/css")]+ cassiusOnly {-# INLINEABLE cassius #-}
src/Network/Wai/Middleware/ContentType/Clay.hs view
@@ -1,8 +1,13 @@+{-# LANGUAGE+ OverloadedStrings+ #-}++ module Network.Wai.Middleware.ContentType.Clay where import Network.Wai.Middleware.ContentType.Types as CT import Network.Wai.Middleware.ContentType.Text-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response) import Clay.Render@@ -14,9 +19,14 @@ clay :: Monad m => Config -> [App] -> Css- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () clay c as i =- tell' $ HM.singleton CT.Css (clayOnly c as i)+ tell' $ HM.singleton CT.Css $+ ResponseVia+ (c,as,i)+ status200+ [("Content-Type","text/css")]+ (\(c,as,i) -> clayOnly c as i) {-# INLINEABLE clay #-}
src/Network/Wai/Middleware/ContentType/Json.hs view
@@ -1,8 +1,12 @@+{-# LANGUAGE+ OverloadedStrings+ #-}+ module Network.Wai.Middleware.ContentType.Json where import Network.Wai.Middleware.ContentType.Types import Network.Wai.Middleware.ContentType.ByteString-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response) import qualified Data.Aeson as A@@ -14,9 +18,10 @@ json :: ( A.ToJSON j , Monad m ) => j- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () json =- bytestring Json . A.encode+ (overFileExts [Json] $ mapHeaders (("Content-Type","application/json"):))+ . bytestring Json . A.encode {-# INLINEABLE json #-}
src/Network/Wai/Middleware/ContentType/Julius.hs view
@@ -1,8 +1,13 @@+{-# LANGUAGE+ OverloadedStrings+ #-}++ module Network.Wai.Middleware.ContentType.Julius where import Network.Wai.Middleware.ContentType.Types as CT import Network.Wai.Middleware.ContentType.Text-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response) import Text.Julius@@ -13,9 +18,14 @@ julius :: Monad m => Javascript- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () julius i =- tell' $ HM.singleton CT.JavaScript (juliusOnly i)+ tell' $ HM.singleton CT.JavaScript $+ ResponseVia+ i+ status200+ [("Content-Type","application/javascript")]+ juliusOnly {-# INLINEABLE julius #-}
src/Network/Wai/Middleware/ContentType/Lucid.hs view
@@ -1,7 +1,11 @@+{-# LANGUAGE+ OverloadedStrings+ #-}+ module Network.Wai.Middleware.ContentType.Lucid where import Network.Wai.Middleware.ContentType.Types-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response, responseBuilder) import qualified Lucid.Base as L@@ -13,10 +17,15 @@ lucid :: Monad m => L.HtmlT m ()- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () lucid i = do- i' <- lift (lucidOnly i)- tell' (HM.singleton Html i')+ f <- lift (lucidOnly i)+ tell' $ HM.singleton Html $+ ResponseVia+ i+ status200+ [("Content-Type","text/html")]+ (const f) {-# INLINEABLE lucid #-}
src/Network/Wai/Middleware/ContentType/Lucius.hs view
@@ -1,8 +1,13 @@+{-# LANGUAGE+ OverloadedStrings+ #-}++ module Network.Wai.Middleware.ContentType.Lucius where import Network.Wai.Middleware.ContentType.Types as CT import Network.Wai.Middleware.ContentType.Text-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response) import Text.Lucius@@ -13,9 +18,14 @@ lucius :: Monad m => Css- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () lucius i =- tell' $ HM.singleton CT.Css (luciusOnly i)+ tell' $ HM.singleton CT.Css $+ ResponseVia+ i+ status200+ [("Content-Type","text/css")]+ luciusOnly {-# INLINEABLE lucius #-}
src/Network/Wai/Middleware/ContentType/Pandoc.hs view
@@ -1,8 +1,13 @@+{-# LANGUAGE+ OverloadedStrings+ #-}++ module Network.Wai.Middleware.ContentType.Pandoc where import Network.Wai.Middleware.ContentType.Types import Network.Wai.Middleware.ContentType.Text-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response) import qualified Data.Text.Lazy as LT@@ -14,9 +19,14 @@ markdown :: Monad m => P.Pandoc- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () markdown i =- tell' $ HM.singleton Markdown (markdownOnly i)+ tell' $ HM.singleton Markdown $+ ResponseVia+ i+ status200+ [("Content-Type","text/markdown")]+ markdownOnly {-# INLINEABLE markdown #-}
src/Network/Wai/Middleware/ContentType/Text.hs view
@@ -1,7 +1,11 @@+{-# LANGUAGE+ OverloadedStrings+ #-}+ module Network.Wai.Middleware.ContentType.Text where import Network.Wai.Middleware.ContentType.Types-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (status200, Status, ResponseHeaders) import Network.Wai (Response, responseBuilder) import qualified Data.Text.Lazy as LT@@ -13,9 +17,14 @@ text :: Monad m => LT.Text- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m ()+ -> FileExtListenerT m () text i =- tell' $ HM.singleton Text (textOnly i)+ tell' $ HM.singleton Text $+ ResponseVia+ i+ status200+ [("Content-Type", "text/plain")]+ textOnly {-# INLINEABLE text #-}
src/Network/Wai/Middleware/ContentType/Types.hs view
@@ -8,6 +8,7 @@ , StandaloneDeriving , UndecidableInstances , MultiParamTypeClasses+ , ExistentialQuantification , GeneralizedNewtypeDeriving #-} @@ -27,10 +28,15 @@ , allFileExts , getFileExt , toExt+ , ResponseVia (..)+ , runResponseVia+ , mapStatus+ , mapHeaders , FileExtMap , FileExtListenerT (..) , execFileExtListenerT- , mapResponse+ , overFileExts+ , mapFileExtMap , -- * Utilities tell' , AcceptHeader@@ -118,9 +124,37 @@ {-# INLINEABLE toExt #-} +-- ayy, lamo. Basically.+data ResponseVia = forall a. ResponseVia+ { responseData :: !a+ , responseStatus :: !Status+ , responseHeaders :: !ResponseHeaders+ , responseFunction :: !(a -> Status -> ResponseHeaders -> Response)+ } -type FileExtMap a = HashMap FileExt a+runResponseVia :: ResponseVia -> Response+runResponseVia (ResponseVia d s hs f) = f d s hs +mapStatus :: (Status -> Status) -> ResponseVia -> ResponseVia+mapStatus f (ResponseVia d s hs f') = ResponseVia d (f s) hs f'++mapHeaders :: (ResponseHeaders -> ResponseHeaders) -> ResponseVia -> ResponseVia+mapHeaders f (ResponseVia d s hs f') = ResponseVia d s (f hs) f'++overFileExts :: Monad m =>+ [FileExt]+ -> (ResponseVia -> ResponseVia)+ -> FileExtListenerT m a+ -> FileExtListenerT m a+overFileExts fs f (FileExtListenerT xs) = do+ i <- get+ let i' = HM.mapWithKey (\k x -> if k `elem` fs then f x else x) i+ (x, o) <- lift (runStateT xs i')+ put o+ pure x++type FileExtMap = HashMap FileExt ResponseVia+ -- | The monad for our DSL - when using the combinators, our result will be this -- type: --@@ -128,43 +162,39 @@ -- > myListener = do -- > text "Text!" -- > json ("Json!" :: T.Text)-newtype FileExtListenerT r m a = FileExtListenerT- { runFileExtListenerT :: StateT (FileExtMap r) m a+newtype FileExtListenerT m a = FileExtListenerT+ { runFileExtListenerT :: StateT FileExtMap m a } deriving ( Functor, Applicative, Alternative, Monad, MonadFix, MonadPlus, MonadIO- , MonadTrans, MonadReader r', MonadWriter w, MonadState (FileExtMap r)+ , MonadTrans, MonadReader r', MonadWriter w, MonadState FileExtMap , MonadCont, MonadError e, MonadBase b, MonadThrow, MonadCatch , MonadMask, MonadLogger, MonadUrl b f, MFunctor ) -deriving instance (MonadResource m, MonadBase IO m) => MonadResource (FileExtListenerT r m)+deriving instance (MonadResource m, MonadBase IO m) => MonadResource (FileExtListenerT m) -instance MonadTransControl (FileExtListenerT r) where- type StT (FileExtListenerT r) a = StT (StateT (FileExtMap r)) a+instance MonadTransControl FileExtListenerT where+ type StT FileExtListenerT a = StT (StateT FileExtMap) a liftWith = defaultLiftWith FileExtListenerT runFileExtListenerT restoreT = defaultRestoreT FileExtListenerT instance ( MonadBaseControl b m- ) => MonadBaseControl b (FileExtListenerT r m) where- type StM (FileExtListenerT r m) a = ComposeSt (FileExtListenerT r) m a+ ) => MonadBaseControl b (FileExtListenerT m) where+ type StM (FileExtListenerT m) a = ComposeSt FileExtListenerT m a liftBaseWith = defaultLiftBaseWith restoreM = defaultRestoreM -mapResponse :: Monad m =>- ((Status -> ResponseHeaders -> Response) -> Response)- -> FileExtListenerT (Status -> ResponseHeaders -> Response) m a- -> FileExtListenerT Response m a-mapResponse f (FileExtListenerT xs) =- FileExtListenerT $ mapState (HM.map f) (HM.map (const . const)) xs- where- mapState to from xs = do- i <- get- (x,s) <- lift (runStateT xs (from i))- put (to s)- pure x--execFileExtListenerT :: Monad m => FileExtListenerT r m a -> m (FileExtMap r)+execFileExtListenerT :: Monad m => FileExtListenerT m a -> m FileExtMap execFileExtListenerT xs = execStateT (runFileExtListenerT xs) mempty +mapFileExtMap :: ( Monad m+ ) => (FileExtMap -> FileExtMap)+ -> FileExtListenerT m a+ -> FileExtListenerT m a+mapFileExtMap f (FileExtListenerT xs) = do+ map <- get+ (x,map') <- lift (runStateT xs (f map))+ put map'+ return x -- * Headers@@ -205,7 +235,7 @@ -- > myApp = do -- > text "foo" -- > invalidEncoding myErrorHandler -- handles all except text/plain-invalidEncoding :: Monad m => r -> FileExtListenerT r m ()+invalidEncoding :: Monad m => ResponseVia -> FileExtListenerT m () invalidEncoding r = mapM_ (\t -> tell' $ HM.singleton t r) allFileExts {-# INLINEABLE invalidEncoding #-}
test/Network/Wai/Middleware/ContentTypeSpec.hs view
@@ -162,8 +162,8 @@ fileExtsToMiddleware allExamples $ (\req respond -> respond (textOnly "Something went wrong" status406 [])) -allExamples :: FileExtListenerT Response IO ()-allExamples = mapResponse (\f -> f status200 []) $ do+allExamples :: FileExtListenerT IO ()+allExamples = do text "Text!" json ("Json!" :: T.Text) lucid (L.toHtmlRaw ("Html!" :: T.Text))
wai-middleware-content-type.cabal view
@@ -1,19 +1,14 @@ Name: wai-middleware-content-type-Version: 0.3.0+Version: 0.4.0 Author: Athan Clark <athan.clark@gmail.com> Maintainer: Athan Clark <athan.clark@gmail.com> License: BSD3 License-File: LICENSE-Synopsis: Route to different middlewares based on the incoming Accept header.+Synopsis: A simple WAI library for responding with content. -- Description: Cabal-Version: >= 1.10 Build-Type: Simple Category: Web---Flag Example- Description: Build a trivial example- Default: False Library