{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.Wai.Routing.Purescheme.Core.Query
( singleParameter
, maybeSingleParameter
)
where
import Network.Wai.Routing.Purescheme.Core.Basic
import Network.Wai.Routing.Purescheme.Core.Internal
import Data.ByteString (ByteString)
import qualified Data.Text as T
import Data.String.Interpolate.IsString (i)
import Network.HTTP.Types (badRequest400, statusMessage)
import Network.Wai (queryString)
singleParameter :: FromUri a => ByteString -> (a -> GenericApplication b) -> GenericApplication b
singleParameter name f req =
case filter (\(k, _) -> k == name) $ queryString req of
[(_, Just value)] -> f (fromByteString value) req
[] -> reject $ invalidParameterRejection [i|Required query parameter not found: #{name}|]
_ -> reject $ invalidParameterRejection
[i|Found more than one parameter in query string, required only one: #{name}|]
maybeSingleParameter ::
FromUri a
=> ByteString
-> (Maybe a -> GenericApplication r)
-> GenericApplication r
maybeSingleParameter name f req =
case filter (\(k, _) -> k == name) $ queryString req of
[(_, Just value)] -> f (Just $ fromByteString value) req
[] -> f Nothing req
_ ->
reject $ invalidParameterRejection
[i|Found more than one parameter in query string, required none or only one: #{name}|]
invalidParameterRejection :: T.Text -> Rejection
invalidParameterRejection errorMessage =
Rejection
{ status = badRequest400
, message = [i|#{statusMessage badRequest400}: #{errorMessage}|]
, priority = 200
, headers = []
}