module Servant.API.Extended.Endpath where

import Data.Metrics.Servant
import Imports
import Servant
import Servant.Server.Internal.Delayed
import Servant.Server.Internal.ErrorFormatter
import Servant.Server.Internal.Router

-- | Doesn't allow any trailing path components when used with 'Raw'
data Endpath

instance (HasServer api context, HasContextEntry (context .++ DefaultErrorFormatters) ErrorFormatters) => HasServer (Endpath :> api) context where
  type ServerT (Endpath :> api) m = ServerT api m

  route :: Proxy (Endpath :> api) -> Context context -> Delayed env (Server (Endpath :> api)) -> Router env
  route :: forall env.
Proxy (Endpath :> api)
-> Context context
-> Delayed env (Server (Endpath :> api))
-> Router env
route Proxy (Endpath :> api)
_ Context context
ctx Delayed env (Server (Endpath :> api))
delayed =
    let fmt404 :: NotFoundErrorFormatter
fmt404 = ErrorFormatters -> NotFoundErrorFormatter
notFoundErrorFormatter (ErrorFormatters -> NotFoundErrorFormatter)
-> ErrorFormatters -> NotFoundErrorFormatter
forall a b. (a -> b) -> a -> b
$ Context (context .++ DefaultErrorFormatters) -> ErrorFormatters
forall (context :: [*]) val.
HasContextEntry context val =>
Context context -> val
getContextEntry (Context (context .++ DefaultErrorFormatters) -> ErrorFormatters)
-> Context (context .++ DefaultErrorFormatters) -> ErrorFormatters
forall a b. (a -> b) -> a -> b
$ Context context -> Context (context .++ DefaultErrorFormatters)
forall (ctx :: [*]).
Context ctx -> Context (MkContextWithErrorFormatter ctx)
mkContextWithErrorFormatter Context context
ctx
     in Map Text (Router' env RoutingApplication)
-> [env -> RoutingApplication] -> Router' env RoutingApplication
forall env a.
Map Text (Router' env a) -> [env -> a] -> Router' env a
StaticRouter Map Text (Router' env RoutingApplication)
forall a. Monoid a => a
mempty ([env -> RoutingApplication] -> Router' env RoutingApplication)
-> [env -> RoutingApplication] -> Router' env RoutingApplication
forall a b. (a -> b) -> a -> b
$ [NotFoundErrorFormatter
-> Router' env RoutingApplication -> env -> RoutingApplication
forall env.
NotFoundErrorFormatter -> Router env -> env -> RoutingApplication
runRouterEnv NotFoundErrorFormatter
fmt404 (Proxy api
-> Context context
-> Delayed env (Server api)
-> Router' env RoutingApplication
forall env.
Proxy api
-> Context context -> Delayed env (Server api) -> Router env
forall {k} (api :: k) (context :: [*]) env.
HasServer api context =>
Proxy api
-> Context context -> Delayed env (Server api) -> Router env
route (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Context context
ctx Delayed env (Server api)
Delayed env (Server (Endpath :> api))
delayed)]

  hoistServerWithContext :: Proxy (Endpath :> api) -> Proxy context -> (forall x. m x -> n x) -> ServerT (Endpath :> api) m -> ServerT (Endpath :> api) n
  hoistServerWithContext :: forall (m :: * -> *) (n :: * -> *).
Proxy (Endpath :> api)
-> Proxy context
-> (forall x. m x -> n x)
-> ServerT (Endpath :> api) m
-> ServerT (Endpath :> api) n
hoistServerWithContext Proxy (Endpath :> api)
_ Proxy context
proxyCtx forall x. m x -> n x
f ServerT (Endpath :> api) m
s = Proxy api
-> Proxy context
-> (forall x. m x -> n x)
-> ServerT api m
-> ServerT api n
forall {k} (api :: k) (context :: [*]) (m :: * -> *) (n :: * -> *).
HasServer api context =>
Proxy api
-> Proxy context
-> (forall x. m x -> n x)
-> ServerT api m
-> ServerT api n
forall (m :: * -> *) (n :: * -> *).
Proxy api
-> Proxy context
-> (forall x. m x -> n x)
-> ServerT api m
-> ServerT api n
hoistServerWithContext (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Proxy context
proxyCtx m x -> n x
forall x. m x -> n x
f ServerT api m
ServerT (Endpath :> api) m
s

-- Endpath :> route
instance (RoutesToPaths route) => RoutesToPaths (Endpath :> route) where
  getRoutes :: Forest PathSegment
getRoutes = forall route. RoutesToPaths route => Forest PathSegment
forall {k} (routes :: k).
RoutesToPaths routes =>
Forest PathSegment
getRoutes @route