eved-0.0.1.0: src/Web/Eved/Options.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
module Web.Eved.Options
where
import qualified Data.ByteString as B
import Data.Coerce (coerce)
import Data.Text (Text)
import Network.HTTP.Types
import Network.Wai
import Web.Eved.Internal
provideOptions :: EvedOptions m a -> Middleware
provideOptions api app req respond
| requestMethod req == "OPTIONS" = respond (getOptionsResponse api req)
| otherwise = app req respond
getOptionsResponse :: EvedOptions m a -> Request -> Response
getOptionsResponse api req =
let methods = fmap renderStdMethod $ getAvailableMethods api (pathInfo req)
headers = [ ("Allow", B.intercalate ", " $ "OPTIONS":methods) ]
in responseBuilder status200 headers mempty
newtype EvedOptions (m :: * -> *) a = EvedOptions
{ getAvailableMethods :: [Text] -> [StdMethod]
}
passthrough :: EvedOptions m a -> EvedOptions m b
passthrough = coerce
instance Eved (EvedOptions m) m where
left .<|> right = EvedOptions $ \path ->
getAvailableMethods left path <> getAvailableMethods right path
lit t next = EvedOptions $ \path ->
case path of
p:rest | p == t -> getAvailableMethods next rest
_ -> mempty
capture _ _ next = EvedOptions $ \path ->
case path of
_:rest -> getAvailableMethods next rest
_ -> mempty
reqBody _ = passthrough
queryParam _ _ = passthrough
verb method _ _ = EvedOptions $ \path ->
case path of
[] -> [method]
_ -> mempty