remove WithArg simplify types

This commit is contained in:
Sönke Hahn 2016-10-24 00:19:44 -04:00
parent 397815fe06
commit fe2df30386
2 changed files with 33 additions and 46 deletions

View file

@ -10,15 +10,21 @@
-- fixme: document dependency problem -- fixme: document dependency problem
module Servant.Server.Utils.CustomCombinators ( module Servant.Server.Utils.CustomCombinators (
-- * ServerCombinator
ServerCombinator, ServerCombinator,
runServerCombinator, runServerCombinator,
-- * Constructing ServerCombinators
makeCaptureCombinator, makeCaptureCombinator,
makeRequestCheckCombinator, makeRequestCheckCombinator,
makeAuthCombinator, makeAuthCombinator,
makeReqBodyCombinator, makeReqBodyCombinator,
makeCombinator, makeCombinator,
-- * re-exports -- * Re-exports
RouteResult(..), RouteResult(..),
) where ) where
@ -34,95 +40,80 @@ import Servant.API
import Servant.Server import Servant.Server
import Servant.Server.Internal import Servant.Server.Internal
data ServerCombinator combinator arg api context where data ServerCombinator combinator serverType api context where
CI :: (forall env . CI :: (forall env .
Proxy (combinator :> api) Proxy (combinator :> api)
-> Context context -> Context context
-> Delayed env (WithArg arg (Server api)) -> Delayed env serverType
-> Router' env RoutingApplication) -> Router' env RoutingApplication)
-> ServerCombinator combinator arg api context -> ServerCombinator combinator serverType api context
-- fixme: get rid of WithArg? runServerCombinator :: ServerCombinator combinator serverType api context
type family WithArg arg rest where
WithArg () rest = rest
WithArg arg rest = arg -> rest
runServerCombinator :: ServerCombinator combinator arg api context
-> Proxy (combinator :> api) -> Proxy (combinator :> api)
-> Context context -> Context context
-> Delayed env (WithArg arg (Server api)) -> Delayed env serverType
-> Router' env RoutingApplication -> Router' env RoutingApplication
runServerCombinator (CI i) = i runServerCombinator (CI i) = i
makeCaptureCombinator :: makeCaptureCombinator ::
(HasServer api context, (HasServer api context) =>
WithArg arg (ServerT api Handler) ~ (arg -> ServerT api Handler)) =>
(Context context -> Text -> IO (RouteResult arg)) (Context context -> Text -> IO (RouteResult arg))
-> ServerCombinator combinator arg api context -> ServerCombinator combinator (arg -> ServerT api Handler) api context
makeCaptureCombinator = inner -- we use 'inner' to avoid having 'forall' show up in haddock docs makeCaptureCombinator = inner -- we use 'inner' to avoid having 'forall' show up in haddock docs
where where
inner :: inner ::
forall api combinator arg context . forall api combinator arg context .
(HasServer api context, (HasServer api context) =>
WithArg arg (ServerT api Handler) ~ (arg -> ServerT api Handler)) =>
(Context context -> Text -> IO (RouteResult arg)) (Context context -> Text -> IO (RouteResult arg))
-> ServerCombinator combinator arg api context -> ServerCombinator combinator (arg -> ServerT api Handler) api context
inner getArg = CI $ \ Proxy context delayed -> inner getArg = CI $ \ Proxy context delayed ->
CaptureRouter $ CaptureRouter $
route (Proxy :: Proxy api) context $ addCapture delayed $ \ captured -> route (Proxy :: Proxy api) context $ addCapture delayed $ \ captured ->
(liftRouteResult =<< liftIO (getArg context captured)) (liftRouteResult =<< liftIO (getArg context captured))
makeRequestCheckCombinator :: makeRequestCheckCombinator ::
(HasServer api context, (HasServer api context) =>
WithArg () (ServerT api Handler) ~ ServerT api Handler) =>
(Context context -> Request -> IO (RouteResult ())) (Context context -> Request -> IO (RouteResult ()))
-> ServerCombinator combinator () api context -> ServerCombinator combinator (ServerT api Handler) api context
makeRequestCheckCombinator = inner makeRequestCheckCombinator = inner
where where
inner :: inner ::
forall api combinator context . forall api combinator context .
(HasServer api context, (HasServer api context) =>
WithArg () (ServerT api Handler) ~ ServerT api Handler) =>
(Context context -> Request -> IO (RouteResult ())) (Context context -> Request -> IO (RouteResult ()))
-> ServerCombinator combinator () api context -> ServerCombinator combinator (ServerT api Handler) api context
inner check = CI $ \ Proxy context delayed -> inner check = CI $ \ Proxy context delayed ->
route (Proxy :: Proxy api) context $ addMethodCheck delayed $ route (Proxy :: Proxy api) context $ addMethodCheck delayed $
withRequest $ \ request -> withRequest $ \ request ->
liftRouteResult =<< liftIO (check context (protectBody "makeRequestCheckCombinator" request)) liftRouteResult =<< liftIO (check context (protectBody "makeRequestCheckCombinator" request))
makeAuthCombinator :: makeAuthCombinator ::
(HasServer api context, (HasServer api context) =>
WithArg arg (ServerT api Handler) ~ (arg -> ServerT api Handler)) =>
(Context context -> Request -> IO (RouteResult arg)) (Context context -> Request -> IO (RouteResult arg))
-> ServerCombinator combinator arg api context -> ServerCombinator combinator (arg -> ServerT api Handler) api context
makeAuthCombinator = inner makeAuthCombinator = inner
where where
inner :: inner ::
forall api combinator arg context . forall api combinator arg context .
(HasServer api context, (HasServer api context) =>
WithArg arg (ServerT api Handler) ~ (arg -> ServerT api Handler)) =>
(Context context -> Request -> IO (RouteResult arg)) (Context context -> Request -> IO (RouteResult arg))
-> ServerCombinator combinator arg api context -> ServerCombinator combinator (arg -> ServerT api Handler) api context
inner authCheck = CI $ \ Proxy context delayed -> inner authCheck = CI $ \ Proxy context delayed ->
route (Proxy :: Proxy api) context $ addAuthCheck delayed $ route (Proxy :: Proxy api) context $ addAuthCheck delayed $
withRequest $ \ request -> withRequest $ \ request ->
liftRouteResult =<< liftIO (authCheck context (protectBody "makeAuthCombinator" request)) liftRouteResult =<< liftIO (authCheck context (protectBody "makeAuthCombinator" request))
makeReqBodyCombinator :: makeReqBodyCombinator ::
(ServerT (combinator :> api) Handler ~ (arg -> ServerT api Handler), (HasServer api context) =>
WithArg arg (ServerT api Handler) ~ (arg -> ServerT api Handler),
HasServer api context) =>
(Context context -> IO ByteString -> arg) (Context context -> IO ByteString -> arg)
-> ServerCombinator combinator arg api context -> ServerCombinator combinator (arg -> ServerT api Handler) api context
makeReqBodyCombinator = inner makeReqBodyCombinator = inner
where where
inner :: inner ::
forall api combinator arg context . forall api combinator arg context .
(ServerT (combinator :> api) Handler ~ (arg -> ServerT api Handler), (HasServer api context) =>
WithArg arg (ServerT api Handler) ~ (arg -> ServerT api Handler),
HasServer api context) =>
(Context context -> IO ByteString -> arg) (Context context -> IO ByteString -> arg)
-> ServerCombinator combinator arg api context -> ServerCombinator combinator (arg -> ServerT api Handler) api context
inner getArg = CI $ \ Proxy context delayed -> inner getArg = CI $ \ Proxy context delayed ->
route (Proxy :: Proxy api) context $ addBodyCheck delayed route (Proxy :: Proxy api) context $ addBodyCheck delayed
(return ()) (return ())
@ -130,20 +121,16 @@ makeReqBodyCombinator = inner
liftRouteResult $ Route $ getArg context $ requestBody request) liftRouteResult $ Route $ getArg context $ requestBody request)
makeCombinator :: makeCombinator ::
(ServerT (combinator :> api) Handler ~ (arg -> ServerT api Handler), (HasServer api context) =>
WithArg arg (ServerT api Handler) ~ (arg -> ServerT api Handler),
HasServer api context) =>
(Context context -> Request -> IO (RouteResult arg)) (Context context -> Request -> IO (RouteResult arg))
-> ServerCombinator combinator arg api context -> ServerCombinator combinator (arg -> ServerT api Handler) api context
makeCombinator = inner makeCombinator = inner
where where
inner :: inner ::
forall api combinator arg context . forall api combinator arg context .
(ServerT (combinator :> api) Handler ~ (arg -> ServerT api Handler), (HasServer api context) =>
WithArg arg (ServerT api Handler) ~ (arg -> ServerT api Handler),
HasServer api context) =>
(Context context -> Request -> IO (RouteResult arg)) (Context context -> Request -> IO (RouteResult arg))
-> ServerCombinator combinator arg api context -> ServerCombinator combinator (arg -> ServerT api Handler) api context
inner getArg = CI $ \ Proxy context delayed -> inner getArg = CI $ \ Proxy context delayed ->
route (Proxy :: Proxy api) context $ addBodyCheck delayed route (Proxy :: Proxy api) context $ addBodyCheck delayed
(return ()) (return ())

View file

@ -269,7 +269,7 @@ data FooHeader
instance HasServer api context => HasServer (FooHeader :> api) context where instance HasServer api context => HasServer (FooHeader :> api) context where
type ServerT (FooHeader :> api) m = String -> ServerT api m type ServerT (FooHeader :> api) m = String -> ServerT api m
route = runServerCombinator $ makeCombinator (const getCustom) route = runServerCombinator $ makeCombinator $ const $ getCustom
getCustom :: Request -> IO (RouteResult String) getCustom :: Request -> IO (RouteResult String)
getCustom request = return $ case lookup "Foo" (requestHeaders request) of getCustom request = return $ case lookup "Foo" (requestHeaders request) of