module Servant.Hateoas.Internal.Sym
(
  -- * Type
  Sym,

  -- * Type family
  Symify
)
where

import Servant
import Servant.Hateoas.HasHandler
import Servant.Hateoas.RelationLink
import GHC.TypeLits

-- | A wrapper for path segments of kind 'Symbol'.
data Sym (sym :: Symbol)

instance (HasServer api context, KnownSymbol sym) => HasServer (Sym sym :> api) context where
  type ServerT (Sym sym :> api) m = ServerT (sym :> api) m
  route :: forall env.
Proxy (Sym sym :> api)
-> Context context
-> Delayed env (Server (Sym sym :> api))
-> Router env
route Proxy (Sym sym :> api)
_ = Proxy (sym :> api)
-> Context context
-> Delayed env (Server (sym :> api))
-> Router' env RoutingApplication
forall env.
Proxy (sym :> api)
-> Context context
-> Delayed env (Server (sym :> 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 @(sym :> api))
  hoistServerWithContext :: forall (m :: * -> *) (n :: * -> *).
Proxy (Sym sym :> api)
-> Proxy context
-> (forall x. m x -> n x)
-> ServerT (Sym sym :> api) m
-> ServerT (Sym sym :> api) n
hoistServerWithContext Proxy (Sym sym :> api)
_ = Proxy (sym :> api)
-> Proxy context
-> (forall {x}. m x -> n x)
-> ServerT (sym :> api) m
-> ServerT (sym :> 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 (sym :> api)
-> Proxy context
-> (forall x. m x -> n x)
-> ServerT (sym :> api) m
-> ServerT (sym :> api) n
hoistServerWithContext (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(sym :> api))

instance (HasLink api, KnownSymbol sym) => HasLink (Sym sym :> api) where
  type MkLink (Sym sym :> api) link = MkLink (sym :> api) link
  toLink :: forall a.
(Link -> a)
-> Proxy (Sym sym :> api) -> Link -> MkLink (Sym sym :> api) a
toLink Link -> a
f Proxy (Sym sym :> api)
_ = (Link -> a) -> Proxy (sym :> api) -> Link -> MkLink (sym :> api) a
forall a.
(Link -> a) -> Proxy (sym :> api) -> Link -> MkLink (sym :> api) a
forall {k} (endpoint :: k) a.
HasLink endpoint =>
(Link -> a) -> Proxy endpoint -> Link -> MkLink endpoint a
toLink Link -> a
f (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(sym :> api))

instance (HasRelationLink api, KnownSymbol sym) => HasRelationLink (Sym sym :> api) where
  toRelationLink :: Proxy (Sym sym :> api) -> RelationLink
toRelationLink Proxy (Sym sym :> api)
_ = Proxy (sym :> api) -> RelationLink
forall {k} (endpoint :: k).
HasRelationLink endpoint =>
Proxy endpoint -> RelationLink
toRelationLink (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(sym :> api))

instance (HasHandler api, KnownSymbol sym) => HasHandler (Sym sym :> api) where
  getHandler :: forall (m :: * -> *).
MonadIO m =>
Proxy m -> Proxy (Sym sym :> api) -> ServerT (Sym sym :> api) m
getHandler Proxy m
m Proxy (Sym sym :> api)
_ = Proxy m -> Proxy (sym :> api) -> ServerT (sym :> api) m
forall {k} (api :: k) (m :: * -> *).
(HasHandler api, MonadIO m) =>
Proxy m -> Proxy api -> ServerT api m
forall (m :: * -> *).
MonadIO m =>
Proxy m -> Proxy (sym :> api) -> ServerT (sym :> api) m
getHandler Proxy m
m (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(sym :> api))

-- | A type family that wraps all path segments of kind 'Symbol' in an API with 'Sym'.
type family Symify api where
  Symify (a :<|> b) = Symify a :<|> Symify b
  Symify ((sym :: Symbol) :> b) = Sym sym :> Symify b
  Symify (a :> b) = a :> Symify b
  Symify a = a