module Network.Wai.Predicate
( module Data.Predicate
, request
, def
, opt
, query
, hasQuery
, header
, hasHeader
, segment
, hasSegment
, cookie
, hasCookie
, accept
, contentType
, fromVault
, module Network.Wai.Predicate.MediaType
, module Network.Wai.Predicate.Error
) where
import Control.Monad (when)
import Data.ByteString (ByteString)
import Data.ByteString.From
import Data.CaseInsensitive (original)
import Data.List (find)
import Data.Maybe (isNothing)
import Data.Predicate
import Data.Vault.Lazy (Key)
import Data.Word
import Network.HTTP.Types
import Network.Wai.Predicate.Accept
import Network.Wai.Predicate.Content
import Network.Wai.Predicate.Error
import Network.Wai.Predicate.MediaType
import Network.Wai.Predicate.Request
import Network.Wai.Predicate.Utility
import Network.Wai
import qualified Data.Vault.Lazy as Vault
def :: a -> Predicate r Error a -> Predicate r Error a
def a = fmap $
result (\e -> if not (TypeError `isReasonOf` e) then return a else Fail e)
Okay
opt :: Predicate r Error a -> Predicate r Error (Maybe a)
opt = fmap $
result (\e -> if not (TypeError `isReasonOf` e) then return Nothing else Fail e)
(\d -> Okay d . Just)
request :: HasRequest r => Predicate r f Request
request = return . getRequest
query :: (HasQuery r, FromByteString a) => ByteString -> Predicate r Error a
query k r =
case lookupQuery k r of
[] -> Fail . addLabel "query" $ notAvailable k
qq -> either (Fail . addLabel "query" . typeError k)
return
(readValues qq)
hasQuery :: HasQuery r => ByteString -> Predicate r Error ()
hasQuery k r =
when (null (lookupQuery k r)) $
(Fail . addLabel "query" $ notAvailable k)
header :: (HasHeaders r, FromByteString a) => HeaderName -> Predicate r Error a
header k r =
case lookupHeader k r of
[] -> Fail . addLabel "header" $ notAvailable (original k)
hh -> either (Fail . addLabel "header" . typeError (original k))
return
(readValues hh)
hasHeader :: HasHeaders r => HeaderName -> Predicate r Error ()
hasHeader k r =
when (isNothing (find ((k ==) . fst) (headers r))) $
(Fail . addLabel "header" $ notAvailable (original k))
segment :: (HasPath r, FromByteString a) => Word -> Predicate r Error a
segment i r =
case lookupSegment i r of
Nothing -> Fail $
e400 & setMessage "Path segment index out of bounds."
. addLabel "path"
Just s -> either (\m -> Fail (e400 & addLabel "path" . setReason TypeError . setMessage m))
return
(readValues [s])
hasSegment :: HasPath r => Word -> Predicate r Error ()
hasSegment i r =
when (isNothing (lookupSegment i r)) $
Fail (e400 & addLabel "path" . setMessage "Path segment index out of bounds.")
cookie :: (HasCookies r, FromByteString a) => ByteString -> Predicate r Error a
cookie k r =
case lookupCookie k r of
[] -> Fail . addLabel "cookie" $ notAvailable k
cc -> either (Fail . addLabel "cookie" . typeError k)
return
(readValues cc)
hasCookie :: HasCookies r => ByteString -> Predicate r Error ()
hasCookie k r =
when (null (lookupCookie k r)) $
(Fail . addLabel "cookie" $ notAvailable k)
fromVault :: HasVault r => Key a -> Predicate r Error a
fromVault k r =
case Vault.lookup k (requestVault r) of
Just a -> return a
Nothing -> Fail $
e500 & setReason NotAvailable
. setMessage "Vault does not contain key."
. addLabel "vault"
notAvailable :: ByteString -> Error
notAvailable k = e400 & setReason NotAvailable . setSource k
typeError :: ByteString -> ByteString -> Error
typeError k m = e400 & setReason TypeError . setSource k . setMessage m