module Control.Monad.Apiary.Filter (
method, Method(..)
, Control.Monad.Apiary.Filter.httpVersion
, http09, http10, http11
, root
, anyPath
, capture
, Capture.path
, Capture.endPath
, Capture.fetch
, QueryKey(..), (??)
, query
, (=:), (=!:), (=?:), (?:), (=*:), (=+:)
, hasQuery
, hasHeader
, eqHeader
, headers
, header
, header'
, ssl
, stdMethod
) where
import Network.Wai as Wai
import qualified Network.HTTP.Types as HT
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Apiary.Action.Internal
import Control.Monad.Apiary.Filter.Internal
import Control.Monad.Apiary.Filter.Internal.Capture.TH
import Control.Monad.Apiary.Internal
import qualified Control.Monad.Apiary.Filter.Internal.Strategy as Strategy
import qualified Control.Monad.Apiary.Filter.Internal.Capture as Capture
import Text.Blaze.Html
import qualified Data.ByteString as S
import qualified Data.ByteString.Char8 as SC
import Data.Monoid
import Data.Proxy
import Data.String
import Data.Reflection
import Data.Apiary.SList
import Data.Apiary.Param
import Data.Apiary.Document
import Data.Apiary.Method
method :: Monad n => Method -> ApiaryT c n m a -> ApiaryT c n m a
method m = focus' (DocMethod m) (Just m) id return
stdMethod :: Monad n => Method -> ApiaryT c n m a -> ApiaryT c n m a
stdMethod = method
ssl :: Monad n => ApiaryT c n m a -> ApiaryT c n m a
ssl = function_ (DocPrecondition "SSL required") isSecure
httpVersion :: Monad n => HT.HttpVersion -> Html -> ApiaryT c n m b -> ApiaryT c n m b
httpVersion v h = function_ (DocPrecondition h) $ (v ==) . Wai.httpVersion
http09 :: Monad n => ApiaryT c n m b -> ApiaryT c n m b
http09 = Control.Monad.Apiary.Filter.httpVersion HT.http09 "HTTP/0.9 only"
http10 :: Monad n => ApiaryT c n m b -> ApiaryT c n m b
http10 = Control.Monad.Apiary.Filter.httpVersion HT.http10 "HTTP/1.0 only"
http11 :: Monad n => ApiaryT c n m b -> ApiaryT c n m b
http11 = Control.Monad.Apiary.Filter.httpVersion HT.http11 "HTTP/1.1 only"
root :: (Functor m, Monad m, Monad n) => ApiaryT c n m b -> ApiaryT c n m b
root = focus' DocRoot Nothing (RootPath:) return
anyPath :: (Functor m, Monad m, Monad n) => ApiaryT c n m b -> ApiaryT c n m b
anyPath = focus' id Nothing (AnyPath:) return
data QueryKey = QueryKey
{ queryKey :: S.ByteString
, queryDesc :: Maybe Html
}
instance IsString QueryKey where
fromString s = QueryKey (SC.pack s) Nothing
(??) :: QueryKey -> Html -> QueryKey
QueryKey k _ ?? d = QueryKey k (Just d)
query :: forall a as w n m b proxy.
(ReqParam a, Strategy.Strategy w, MonadIO n)
=> QueryKey
-> proxy (w a)
-> ApiaryT (Strategy.SNext w as a) n m b
-> ApiaryT as n m b
query QueryKey{..} p =
focus doc $ \l -> do
r <- getRequest
(q,f) <- getRequestBody
maybe mzero return $
Strategy.readStrategy id ((queryKey ==) . fst) p
(reqParams (Proxy :: Proxy a) r q f) l
where
doc = DocQuery queryKey (Strategy.strategyRep (Proxy :: Proxy w)) (reqParamRep (Proxy :: Proxy a)) queryDesc
(=:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as a) n m b -> ApiaryT as n m b
k =: t = query k (Strategy.pFirst t)
(=!:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as a) n m b -> ApiaryT as n m b
k =!: t = query k (Strategy.pOne t)
(=?:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as (Maybe a)) n m b -> ApiaryT as n m b
k =?: t = query k (Strategy.pOption t)
(?:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT as n m b -> ApiaryT as n m b
k ?: t = query k (Strategy.pCheck t)
(=*:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as [a]) n m b -> ApiaryT as n m b
k =*: t = query k (Strategy.pMany t)
(=+:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as [a]) n m b -> ApiaryT as n m b
k =+: t = query k (Strategy.pSome t)
hasQuery :: (MonadIO n) => QueryKey -> ApiaryT c n m a -> ApiaryT c n m a
hasQuery q = query q (Proxy :: Proxy (Strategy.Check ()))
hasHeader :: Monad n => HT.HeaderName -> ApiaryT as n m b -> ApiaryT as n m b
hasHeader n = header' Strategy.pCheck ((n ==) . fst) . Just $
toHtml (show n) <> " header requred"
eqHeader :: Monad n
=> HT.HeaderName
-> S.ByteString
-> ApiaryT as n m b
-> ApiaryT as n m b
eqHeader k v = header' Strategy.pCheck (\(k',v') -> k == k' && v == v') . Just $
mconcat [toHtml $ show k, " header == ", toHtml $ show v]
header :: Monad n => HT.HeaderName
-> ApiaryT (Snoc as S.ByteString) n m b -> ApiaryT as n m b
header n = header' Strategy.pFirst ((n ==) . fst) . Just $
toHtml (show n) <> " header requred"
headers :: Monad n => HT.HeaderName
-> ApiaryT (Snoc as [S.ByteString]) n m b -> ApiaryT as n m b
headers n = header' limit100 ((n ==) . fst) . Just $
toHtml (show n) <> " header requred"
where
limit100 :: Proxy x -> Proxy (Strategy.LimitSome $(int 100) x)
limit100 _ = Proxy
header' :: (Strategy.Strategy w, Monad n)
=> (forall x. Proxy x -> Proxy (w x))
-> (HT.Header -> Bool)
-> Maybe Html
-> ApiaryT (Strategy.SNext w as S.ByteString) n m b
-> ApiaryT as n m b
header' pf kf d = function pc $ \l r ->
Strategy.readStrategy Just kf (pf pByteString) (requestHeaders r) l
where
pc = maybe id DocPrecondition d