{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Internal.Rpc.Export (export) where

import Capnp.Rpc.Common (Client (..))
import Capnp.Rpc.Server
import qualified Capnp.Rpc.Untyped as URpc
import Control.Monad.STM.Class (MonadSTM (liftSTM))
import Data.Proxy (Proxy (..))
import Supervisors (Supervisor)

-- | Export the server as a client for interface @i@. Spawns a server thread
-- with its lifetime bound to the supervisor.
export :: forall i s m. (MonadSTM m, Export i, Server i s, SomeServer s) => Supervisor -> s -> m (Client i)
export :: forall i s (m :: * -> *).
(MonadSTM m, Export i, Server i s, SomeServer s) =>
Supervisor -> s -> m (Client i)
export Supervisor
sup s
srv = forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM forall a b. (a -> b) -> a -> b
$ forall a. Client -> Client a
Client forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadSTM m =>
Supervisor -> ServerOps -> m Client
URpc.export Supervisor
sup (forall i s.
(Export i, Server i s, SomeServer s) =>
Proxy i -> s -> ServerOps
exportToServerOps (forall {k} (t :: k). Proxy t
Proxy @i) s
srv)