-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.

{-# LANGUAGE OverloadedStrings #-}

-- | 'Predicate's which are specific to @wai-routing@.
-- Please note that these can be freely combined with other predicates from
-- @wai-predicates@.
module Network.Wai.Routing.Predicate where

import Control.Monad (when)
import Data.ByteString (ByteString)
import Data.ByteString.Conversion
import Network.Wai.Predicate
import Network.Wai.Predicate.Request
import Network.Wai.Predicate.Utility
import Network.Wai.Routing.Request

-- | Request path parameters.
capture :: (HasCaptures r, FromByteString a) => ByteString -> Predicate r Error a
capture :: forall r a.
(HasCaptures r, FromByteString a) =>
ByteString -> Predicate r Error a
capture ByteString
k r
r = case ByteString -> r -> [ByteString]
forall r. HasCaptures r => ByteString -> r -> [ByteString]
lookupCapture ByteString
k r
r of
    [] -> Error -> Result Error a
forall f t. f -> Result f t
Fail (Error -> Result Error a) -> Error -> Result Error a
forall a b. (a -> b) -> a -> b
$ Error
e400 Error -> (Error -> Error) -> Error
forall a b. a -> (a -> b) -> b
& ByteString -> Error -> Error
addLabel ByteString
"path" (Error -> Error) -> (Error -> Error) -> Error -> Error
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reason -> Error -> Error
setReason Reason
NotAvailable (Error -> Error) -> (Error -> Error) -> Error -> Error
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Error -> Error
setSource ByteString
k
    [ByteString]
cc -> (ByteString -> Result Error a)
-> (a -> Result Error a) -> Either ByteString a -> Result Error a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\ByteString
m -> Error -> Result Error a
forall f t. f -> Result f t
Fail (Error -> Result Error a) -> Error -> Result Error a
forall a b. (a -> b) -> a -> b
$ Error
e400 Error -> (Error -> Error) -> Error
forall a b. a -> (a -> b) -> b
& ByteString -> Error -> Error
addLabel ByteString
"path" (Error -> Error) -> (Error -> Error) -> Error -> Error
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reason -> Error -> Error
setReason Reason
TypeError (Error -> Error) -> (Error -> Error) -> Error -> Error
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Error -> Error
setSource ByteString
k (Error -> Error) -> (Error -> Error) -> Error -> Error
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Error -> Error
setMessage ByteString
m)
                 a -> Result Error a
forall a. a -> Result Error a
forall (m :: * -> *) a. Monad m => a -> m a
return
                 ([ByteString] -> Either ByteString a
forall a. FromByteString a => [ByteString] -> Either ByteString a
readValues [ByteString]
cc)

-- | Request path parameters.
hasCapture :: (HasCaptures r) => ByteString -> Predicate r Error ()
hasCapture :: forall r. HasCaptures r => ByteString -> Predicate r Error ()
hasCapture ByteString
k r
r =
    Bool -> Result Error () -> Result Error ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([ByteString] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (ByteString -> r -> [ByteString]
forall r. HasCaptures r => ByteString -> r -> [ByteString]
lookupCapture ByteString
k r
r)) (Result Error () -> Result Error ())
-> Result Error () -> Result Error ()
forall a b. (a -> b) -> a -> b
$
        Error -> Result Error ()
forall f t. f -> Result f t
Fail (Error
e400 Error -> (Error -> Error) -> Error
forall a b. a -> (a -> b) -> b
& ByteString -> Error -> Error
addLabel ByteString
"path" (Error -> Error) -> (Error -> Error) -> Error -> Error
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reason -> Error -> Error
setReason Reason
NotAvailable (Error -> Error) -> (Error -> Error) -> Error -> Error
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Error -> Error
setSource ByteString
k)

-- | @param \"foo\"@ is equivalent to @query \"foo\" .|. capture \"foo\"@
param :: (HasCaptures r, HasQuery r, FromByteString a) => ByteString -> Predicate r Error a
param :: forall r a.
(HasCaptures r, HasQuery r, FromByteString a) =>
ByteString -> Predicate r Error a
param ByteString
k = ByteString -> Predicate r Error a
forall r a.
(HasQuery r, FromByteString a) =>
ByteString -> Predicate r Error a
query ByteString
k Predicate r Error a -> Predicate r Error a -> Predicate r Error a
forall a f t. Predicate a f t -> Predicate a f t -> Predicate a f t
.|. ByteString -> Predicate r Error a
forall r a.
(HasCaptures r, FromByteString a) =>
ByteString -> Predicate r Error a
capture ByteString
k

hasParam :: (HasCaptures r, HasQuery r) => ByteString -> Predicate r Error ()
hasParam :: forall r.
(HasCaptures r, HasQuery r) =>
ByteString -> Predicate r Error ()
hasParam ByteString
k = ByteString -> Predicate r Error ()
forall r. HasQuery r => ByteString -> Predicate r Error ()
hasQuery ByteString
k Predicate r Error ()
-> Predicate r Error () -> Predicate r Error ()
forall a f t. Predicate a f t -> Predicate a f t -> Predicate a f t
.|. ByteString -> Predicate r Error ()
forall r. HasCaptures r => ByteString -> Predicate r Error ()
hasCapture ByteString
k