-- 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 #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiParamTypeClasses #-} -- | Predicates against path parameters. -- When declaring routes, paths may contain \"variables\" which -- capture whatever is given at that position by an actual request. -- For example: -- -- @ -- get \"\/user\/:name\/address\/:street\" handler $ -- Capture \"name\" :&: Capture \"street\" -- @ -- -- extracts from a request path whatever is given for @:name@ -- and @:street@. module Network.Wai.Routing.Predicate.Capture ( Capture , HasCapture , capture , hasCapture ) where import Data.ByteString (ByteString) import Data.ByteString.From import Data.Monoid import Network.HTTP.Types.Status import Network.Wai.Routing.Error import Network.Wai.Routing.Internal import Network.Wai.Routing.Predicate.Predicate import Network.Wai.Routing.Request newtype Capture a = Capture ByteString capture :: ByteString -> Capture a capture = Capture {-# INLINABLE capture #-} instance (FromByteString a) => Predicate (Capture a) Req where type FVal (Capture a) = Error type TVal (Capture a) = a apply (Capture x) = let msg = "Missing path parameter '" <> x <> "'." in rqApply (lookupCapture x) readValues (err status400 msg) newtype HasCapture = HasCapture ByteString hasCapture :: ByteString -> HasCapture hasCapture = HasCapture {-# INLINABLE hasCapture #-} instance Predicate HasCapture Req where type FVal HasCapture = Error type TVal HasCapture = () apply (HasCapture x) r = if null (lookupCapture x r) then F (err status400 ("Missing path parameter '" <> x <> "'.")) else T 0 ()