{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Capnp.Rpc.Server
( Server (..),
ServerOps (..),
CallInfo (..),
runServer,
MethodHandler,
UntypedMethodHandler,
handleUntypedMethod,
untypedHandler,
toUntypedHandler,
fromUntypedHandler,
)
where
import Capnp.Message (Mutability (..))
import Capnp.Rpc.Promise (Fulfiller)
import Capnp.Untyped (Ptr)
import Control.Concurrent.STM
import Data.Typeable (Typeable)
import Data.Word
import qualified Internal.TCloseQ as TCloseQ
newtype MethodHandler p r = MethodHandler
{ forall p r.
MethodHandler p r
-> Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod ::
Maybe (Ptr 'Const) ->
Fulfiller (Maybe (Ptr 'Const)) ->
IO ()
}
type UntypedMethodHandler = MethodHandler (Maybe (Ptr 'Const)) (Maybe (Ptr 'Const))
handleUntypedMethod :: UntypedMethodHandler -> Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleUntypedMethod :: UntypedMethodHandler
-> Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleUntypedMethod = forall p r.
MethodHandler p r
-> Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod
toUntypedHandler :: MethodHandler p r -> UntypedMethodHandler
toUntypedHandler :: forall p r. MethodHandler p r -> UntypedMethodHandler
toUntypedHandler MethodHandler {Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod :: Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod :: forall p r.
MethodHandler p r
-> Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
..} = MethodHandler {Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod :: Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod :: Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
..}
fromUntypedHandler :: UntypedMethodHandler -> MethodHandler p r
fromUntypedHandler :: forall p r. UntypedMethodHandler -> MethodHandler p r
fromUntypedHandler MethodHandler {Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod :: Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod :: forall p r.
MethodHandler p r
-> Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
..} = MethodHandler {Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod :: Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod :: Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
..}
untypedHandler ::
(Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()) ->
MethodHandler (Maybe (Ptr 'Const)) (Maybe (Ptr 'Const))
untypedHandler :: (Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ())
-> UntypedMethodHandler
untypedHandler = forall p r.
(Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ())
-> MethodHandler p r
MethodHandler
class Server a where
shutdown :: a -> IO ()
shutdown a
_ = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
unwrap :: Typeable b => a -> Maybe b
unwrap a
_ = forall a. Maybe a
Nothing
data ServerOps = ServerOps
{
ServerOps -> Word64 -> Word16 -> UntypedMethodHandler
handleCall ::
Word64 ->
Word16 ->
MethodHandler (Maybe (Ptr 'Const)) (Maybe (Ptr 'Const)),
ServerOps -> IO ()
handleStop :: IO (),
ServerOps -> forall a. Typeable a => Maybe a
handleCast :: forall a. Typeable a => Maybe a
}
data CallInfo = CallInfo
{
CallInfo -> Word64
interfaceId :: !Word64,
CallInfo -> Word16
methodId :: !Word16,
CallInfo -> Maybe (Ptr 'Const)
arguments :: Maybe (Ptr 'Const),
CallInfo -> Fulfiller (Maybe (Ptr 'Const))
response :: Fulfiller (Maybe (Ptr 'Const))
}
runServer :: TCloseQ.Q CallInfo -> ServerOps -> IO ()
runServer :: Q CallInfo -> ServerOps -> IO ()
runServer Q CallInfo
q ServerOps
ops = IO ()
go
where
go :: IO ()
go =
forall a. STM a -> IO a
atomically (forall a. Q a -> STM (Maybe a)
TCloseQ.read Q CallInfo
q) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe CallInfo
Nothing ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just CallInfo {Word64
interfaceId :: Word64
interfaceId :: CallInfo -> Word64
interfaceId, Word16
methodId :: Word16
methodId :: CallInfo -> Word16
methodId, Maybe (Ptr 'Const)
arguments :: Maybe (Ptr 'Const)
arguments :: CallInfo -> Maybe (Ptr 'Const)
arguments, Fulfiller (Maybe (Ptr 'Const))
response :: Fulfiller (Maybe (Ptr 'Const))
response :: CallInfo -> Fulfiller (Maybe (Ptr 'Const))
response} -> do
forall p r.
MethodHandler p r
-> Maybe (Ptr 'Const) -> Fulfiller (Maybe (Ptr 'Const)) -> IO ()
handleMethod
(ServerOps -> Word64 -> Word16 -> UntypedMethodHandler
handleCall ServerOps
ops Word64
interfaceId Word16
methodId)
Maybe (Ptr 'Const)
arguments
Fulfiller (Maybe (Ptr 'Const))
response
IO ()
go