{-# language OverloadedStrings #-}
{-# language FlexibleContexts #-}
{-# language ConstraintKinds #-}
{-# language ViewPatterns #-}
module RubiX.RubixRequest
( getPath
, getPathInfo
, getMethod
, getQueryString
, getQueries
, getQueriesMulti
, getQuery
, getQueryMulti
, getHeader
, getHeaderMulti
, getHeaders
, getBody
, checkSecure
, waiRequest
, matchPaths
) where
import Control.Monad.Reader
import Data.Maybe
import Data.Bifunctor
import qualified Data.Text as DT
import qualified Data.Map as DM
import qualified Data.CaseInsensitive as DCI
import Text.Regex.PCRE
import qualified Network.Wai as NW
import RubiX.Utils
import RubiX.Types
type ReqReader b = MonadReader ReqContext b
fromReq :: ReqReader b => (NW.Request -> a) -> b a
fromReq getter = asks (getter . request)
getHeader :: ReqReader b => DT.Text -> b (Maybe DT.Text)
getHeader key = listToMaybe <$> getHeaderMulti key
getHeaderMulti :: ReqReader b => DT.Text -> b [DT.Text]
getHeaderMulti key = fromMaybe [] . DM.lookup (DCI.mk key) <$> getHeaders
getHeaders :: ReqReader b => b HeaderMap
getHeaders = convertHeaders <$> fromReq NW.requestHeaders
getPath :: ReqReader b => b DT.Text
getPath = fromByteString <$> fromReq NW.rawPathInfo
getMethod :: ReqReader b => b DT.Text
getMethod = fromByteString <$> fromReq NW.requestMethod
getQueryString :: ReqReader b => b DT.Text
getQueryString = fromByteString <$> fromReq NW.rawQueryString
getBody :: ReqReader b => b DT.Text
getBody = asks requestBody
checkSecure :: ReqReader b => b Bool
checkSecure = fromReq NW.isSecure
getPathInfo :: ReqReader b => b [DT.Text]
getPathInfo = fromReq NW.pathInfo
waiRequest :: ReqReader b => b NW.Request
waiRequest = asks request
getQueriesMulti :: ReqReader b => b MultiQueryMap
getQueriesMulti = convertQueries <$> fromReq NW.queryString
getQueries :: ReqReader b => b QueryMap
getQueries = simpleQuery <$> fromReq NW.queryString
getQueryMulti :: ReqReader b => DT.Text -> b [DT.Text]
getQueryMulti key = fromMaybe [] . DM.lookup key <$> getQueriesMulti
getQuery :: ReqReader b => DT.Text -> b (Maybe DT.Text)
getQuery key = DM.lookup key <$> getQueries
matchPaths :: ReqReader b => Pattern -> b Bool
matchPaths pattern = checkMatch pattern <$> getPath
where
checkMatch :: Pattern -> Route -> Bool
checkMatch (DT.unpack -> pat) (DT.unpack -> rt) = rt =~ ("^" ++ pat ++ "$")