packages feed

network-msgpack-rpc 0.0.2 → 0.0.3

raw patch · 11 files changed

+370/−19 lines, 11 filesdep +MissingHPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: MissingH

API changes (from Hackage documentation)

- Network.MessagePack.Client: data Client a
- Network.MessagePack.Client: rpcc :: RpcType r => String -> [Object] -> r
+ Network.MessagePack.Client: data ClientT m a
+ Network.MessagePack.Client: type Client a = ClientT IO a
+ Network.MessagePack.Interface: call :: RpcType (ClientType m f) => InterfaceM m f -> ClientType m f
+ Network.MessagePack.Interface: concrete :: Interface f -> InterfaceM m f
+ Network.MessagePack.Interface: data Interface f
+ Network.MessagePack.Interface: data Returns r
+ Network.MessagePack.Interface: interface :: String -> Doc f -> Interface f
+ Network.MessagePack.Interface: method :: (MonadThrow m, MethodType m (ServerType m f), IsDocType f, IsReturnType m f) => Interface f -> HaskellType f -> Method m
+ Network.MessagePack.Interface: methodIO :: (MethodType m (ServerTypeIO m f), IsDocType f, IsReturnTypeIO m f) => Interface f -> HaskellTypeIO f -> Method m
+ Network.MessagePack.Rpc: data Returns r
+ Network.MessagePack.Rpc: data RpcIOT mc ms f
+ Network.MessagePack.Rpc: data RpcT mc ms f
+ Network.MessagePack.Rpc: docs :: RpcService rpc => rpc -> (String, Doc (F rpc))
+ Network.MessagePack.Rpc: instance Network.MessagePack.Rpc.RpcService (Network.MessagePack.Rpc.RpcIOT mc ms f)
+ Network.MessagePack.Rpc: instance Network.MessagePack.Rpc.RpcService (Network.MessagePack.Rpc.RpcT mc ms f)
+ Network.MessagePack.Rpc: method :: RpcService rpc => rpc -> Method (ServerMonad rpc)
+ Network.MessagePack.Rpc: rpc :: RpcService rpc => rpc -> ClientType (ClientMonad rpc) (F rpc)
+ Network.MessagePack.Rpc: stubs :: (RpcType (ClientType mc f), MethodType ms (ServerType ms f), IsReturnType ms f, IsDocType f, MonadThrow ms) => String -> Doc f -> HaskellType f -> RpcT mc ms f
+ Network.MessagePack.Rpc: stubsIO :: (RpcType (ClientType mc f), MethodType ms (ServerTypeIO ms f), IsReturnTypeIO ms f, IsDocType f, MonadThrow ms) => String -> Doc f -> HaskellTypeIO f -> RpcIOT mc ms f
+ Network.MessagePack.Rpc: type Rpc f = RpcT IO IO f
+ Network.MessagePack.Rpc: type RpcIO f = RpcIOT IO IO f
+ Network.MessagePack.Server: MethodDocs :: [MethodVal] -> MethodVal -> MethodDocs
+ Network.MessagePack.Server: MethodVal :: String -> String -> MethodVal
+ Network.MessagePack.Server: [methodArgs] :: MethodDocs -> [MethodVal]
+ Network.MessagePack.Server: [methodRetv] :: MethodDocs -> MethodVal
+ Network.MessagePack.Server: [valName] :: MethodVal -> String
+ Network.MessagePack.Server: [valType] :: MethodVal -> String
+ Network.MessagePack.Server: data MethodDocs
+ Network.MessagePack.Server: data MethodVal
+ Network.MessagePack.Server: methodDocs :: Method m -> MethodDocs
+ Network.MessagePack.Server: methodName :: Method m -> String
- Network.MessagePack.Server: method :: MethodType m f => String -> f -> Method m
+ Network.MessagePack.Server: method :: MethodType m f => String -> MethodDocs -> f -> Method m

Files

network-msgpack-rpc.cabal view
@@ -1,5 +1,5 @@ name:                 network-msgpack-rpc-version:              0.0.2+version:              0.0.3 synopsis:             A MessagePack-RPC Implementation homepage:             http://msgpack.org/ license:              BSD3@@ -26,20 +26,26 @@   default-language: Haskell2010   ghc-options:       -Wall+      -fno-warn-unused-imports   hs-source-dirs:       src   exposed-modules:       Network.MessagePack.Client+      Network.MessagePack.Interface+      Network.MessagePack.Rpc       Network.MessagePack.Server   other-modules:       Network.MessagePack.Capabilities       Network.MessagePack.Client.Basic       Network.MessagePack.Client.Internal+      Network.MessagePack.Interface.Internal+      Network.MessagePack.Internal.TypeUtil       Network.MessagePack.Protocol       Network.MessagePack.Server.Basic       Network.MessagePack.Types   build-depends:       base < 5+    , MissingH     , binary     , binary-conduit     , bytestring
src/Network/MessagePack/Client.hs view
@@ -3,6 +3,7 @@ module Network.MessagePack.Client (   -- * MessagePack Client type     Client+  , ClientT   , execClient   , runClient @@ -11,7 +12,7 @@    -- * RPC error   , RpcError (..)-  , RpcType (..)+  , RpcType   ) where  import           Control.Applicative                 (Applicative, pure)
src/Network/MessagePack/Client/Basic.hs view
@@ -31,6 +31,7 @@ module Network.MessagePack.Client.Basic (   -- * MessagePack Client type     Client+  , ClientT   , execClient    -- * Call RPC method@@ -42,7 +43,7 @@   ) where  import           Control.Monad.Catch                 (MonadThrow, throwM)-import           Control.Monad.State.Strict          as CMS+import qualified Control.Monad.State.Strict          as CMS import qualified Data.ByteString                     as S import           Data.Conduit                        (($$+)) import           Data.Conduit.Network                (appSink, appSource,@@ -60,7 +61,7 @@ execClient host port client =   runTCPClient (clientSettings port host) $ \ad -> do     (rsrc, _) <- appSource ad $$+ return ()-    evalStateT (runClient client) Connection+    CMS.evalStateT (runClientT client) Connection       { connSource = rsrc       , connSink   = appSink ad       , connMsgId  = 0@@ -72,7 +73,8 @@   rpcc :: String -> [Object] -> r  -instance MessagePack o => RpcType (Client o) where+instance (CMS.MonadIO m, MonadThrow m, MessagePack o)+    => RpcType (ClientT m o) where   rpcc name args = do     res <- rpcCall name (reverse args)     case fromObject res of
src/Network/MessagePack/Client/Internal.hs view
@@ -2,10 +2,11 @@ module Network.MessagePack.Client.Internal where  import           Control.Applicative               (Applicative)+import           Control.Monad                     (when) import           Control.Monad.Catch               (MonadCatch, MonadThrow,                                                     throwM)-import           Control.Monad.State.Strict        as CMS-import           Data.Binary                       as Binary+import qualified Control.Monad.State.Strict        as CMS+import qualified Data.Binary                       as Binary import qualified Data.ByteString                   as S import           Data.Conduit                      (ResumableSource, Sink, ($$),                                                     ($$++))@@ -17,25 +18,27 @@   -- | RPC connection type-data Connection = Connection-  { connSource :: ResumableSource IO S.ByteString-  , connSink   :: Sink S.ByteString IO ()+data Connection m = Connection+  { connSource :: ResumableSource m S.ByteString+  , connSink   :: Sink S.ByteString m ()   , connMsgId  :: Int   , connMths   :: [String]   }  -newtype Client a-  = ClientT { runClient :: StateT Connection IO a }-  deriving (Functor, Applicative, Monad, MonadIO, MonadThrow, MonadCatch)+newtype ClientT m a+  = ClientT { runClientT :: CMS.StateT (Connection m) m a }+  deriving (Functor, Applicative, Monad, CMS.MonadIO, MonadThrow, MonadCatch) +type Client a = ClientT IO a -rpcCall :: String -> [Object] -> Client Object++rpcCall :: (MonadThrow m, CMS.MonadIO m) => String -> [Object] -> ClientT m Object rpcCall methodName args = ClientT $ do   conn <- CMS.get   let msgid = connMsgId conn -  (rsrc', res) <- lift $ do+  (rsrc', res) <- CMS.lift $ do     let req = packRequest (connMths conn) (0, msgid, methodName, args)     CB.sourceLbs req $$ connSink conn     connSource conn $$++ sinkGet Binary.get@@ -61,7 +64,7 @@         Just () -> return rresult  -setMethodList :: [String] -> Client ()+setMethodList :: Monad m => [String] -> ClientT m () setMethodList mths = ClientT $ do   conn <- CMS.get   CMS.put conn { connMths = mths }
+ src/Network/MessagePack/Interface.hs view
@@ -0,0 +1,12 @@+module Network.MessagePack.Interface+  ( Returns+  , Interface+  , interface+  , call+  , concrete+  , method+  , methodIO+  , Doc (Arg, Ret)+  ) where++import           Network.MessagePack.Interface.Internal
+ src/Network/MessagePack/Interface/Internal.hs view
@@ -0,0 +1,190 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE InstanceSigs          #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE StandaloneDeriving    #-}+{-# LANGUAGE TypeFamilies          #-}+module Network.MessagePack.Interface.Internal where++import           Control.Monad.Catch                   (MonadThrow)+import           Control.Monad.Trans                   (MonadIO, liftIO)+import           Data.Typeable                         (Typeable)++import           Network.MessagePack.Client            (ClientT)+import qualified Network.MessagePack.Client            as Client+import qualified Network.MessagePack.Internal.TypeUtil as TypeUtil+import           Network.MessagePack.Server            (Method, MethodDocs (..),+                                                        MethodVal (..), ServerT)+import qualified Network.MessagePack.Server            as Server+++data Returns r+++data Interface f = Interface+  { name :: String+  , docs :: Doc f+  }+++data InterfaceM (m :: * -> *) f = InterfaceM+  { nameM :: String+  }+++interface :: String -> Doc f -> Interface f+interface = Interface+++concrete :: Interface f -> InterfaceM m f+concrete = InterfaceM . name+++coerce :: InterfaceM m a -> InterfaceM m b+coerce = InterfaceM . nameM+++--------------------------------------------------------------------------------+--+-- :: Documentation+--+--------------------------------------------------------------------------------+++class IsDocType f where+  data Doc f+  flatDoc :: Doc f -> MethodDocs++instance Typeable r => IsDocType (Returns r) where+  data Doc (Returns r) = Ret String+    deriving (Eq, Read, Show)+  flatDoc (Ret x) =+    let typeName = TypeUtil.typeName (undefined :: r) in+    MethodDocs [] (MethodVal x typeName)++instance (Typeable o, IsDocType r) => IsDocType (o -> r) where+  data Doc (o -> r) = Arg String (Doc r)+  flatDoc (Arg o r) =+    let doc = flatDoc r in+    let typeName = TypeUtil.typeName (undefined :: o) in+    doc { methodArgs = MethodVal o typeName : methodArgs doc }++deriving instance Eq   (Doc r) => Eq   (Doc (o -> r))+deriving instance Read (Doc r) => Read (Doc (o -> r))+deriving instance Show (Doc r) => Show (Doc (o -> r))+++--------------------------------------------------------------------------------+--+-- :: Client+--+--------------------------------------------------------------------------------+++class IsClientType (m :: * -> *) f where+  type ClientType m f++instance IsClientType m (Returns r) where+  type ClientType m (Returns r) = ClientT m r++instance IsClientType m r => IsClientType m (o -> r) where+  type ClientType m (o -> r) = o -> ClientType m r+++call :: Client.RpcType (ClientType m f) => InterfaceM m f -> ClientType m f+call = Client.call . nameM+++--------------------------------------------------------------------------------+--+-- :: Non-IO server+--+--------------------------------------------------------------------------------+++class IsReturnType (m :: * -> *) f where+  type HaskellType f+  type ServerType m f++  implement :: InterfaceM m f -> HaskellType f -> ServerType m f++instance Monad m => IsReturnType m (Returns r) where+  type HaskellType (Returns r) = r+  type ServerType m (Returns r) = ServerT m r++  implement _ = return++instance IsReturnType m r => IsReturnType m (o -> r) where+  type HaskellType (o -> r) = o -> HaskellType r+  type ServerType m (o -> r) = o -> ServerType m r++  implement i f a = next (coerce i) (f a)+    where+      next :: InterfaceM m r -> HaskellType r -> ServerType m r+      next = implement+++methodM+  :: ( Server.MethodType m (ServerType m f)+     , IsDocType f+     , IsReturnType m f+     , MonadThrow m+     )+  => InterfaceM m f -> Doc f -> HaskellType f -> Method m+methodM i doc f = Server.method (nameM i) (flatDoc doc) (implement i f)+++method+  :: ( MonadThrow m+     , Server.MethodType m (ServerType m f)+     , IsDocType f+     , IsReturnType m f)+  => Interface f -> HaskellType f -> Method m+method i = methodM (concrete i) (docs i)+++--------------------------------------------------------------------------------+--+-- :: IO server+--+--------------------------------------------------------------------------------+++class IsReturnTypeIO (m :: * -> *) f where+  type HaskellTypeIO f+  type ServerTypeIO m f++  implementIO :: InterfaceM m f -> HaskellTypeIO f -> ServerTypeIO m f++instance MonadIO m => IsReturnTypeIO m (Returns r) where+  type HaskellTypeIO (Returns r) = IO r+  type ServerTypeIO m (Returns r) = ServerT m r++  implementIO _ = liftIO++instance IsReturnTypeIO m r => IsReturnTypeIO m (o -> r) where+  type HaskellTypeIO (o -> r) = o -> HaskellTypeIO r+  type ServerTypeIO m (o -> r) = o -> ServerTypeIO m r++  implementIO i f a = next (coerce i) (f a)+    where+      next :: InterfaceM m r -> HaskellTypeIO r -> ServerTypeIO m r+      next = implementIO+++methodIOM+  :: ( Server.MethodType m (ServerTypeIO m f)+     , IsDocType f+     , IsReturnTypeIO m f+     )+  => InterfaceM m f -> Doc f -> HaskellTypeIO f -> Method m+methodIOM i doc f = Server.method (nameM i) (flatDoc doc) (implementIO i f)+++methodIO+  :: ( Server.MethodType m (ServerTypeIO m f)+     , IsDocType f+     , IsReturnTypeIO m f)+  => Interface f -> HaskellTypeIO f -> Method m+methodIO i = methodIOM (concrete i) (docs i)
+ src/Network/MessagePack/Internal/TypeUtil.hs view
@@ -0,0 +1,9 @@+module Network.MessagePack.Internal.TypeUtil where++import qualified Data.List.Utils as List+import           Data.Typeable   (Typeable)+import qualified Data.Typeable   as Typeable+++typeName :: Typeable a => a -> String+typeName = List.replace "[Char]" "String" . show . Typeable.typeOf
src/Network/MessagePack/Protocol.hs view
@@ -44,6 +44,8 @@   => [Method m]   -> [Method m] protocolMethods methods = methods ++-  [ method capabilitiesN (capabilitiesS methods)-  , method methodListN   (methodListS   methods)+  [ method capabilitiesN (MethodDocs [MethodVal "clientCaps" "ClientCapability"] (MethodVal "serverCaps" "ServerCapability"))+      (capabilitiesS methods)+  , method methodListN   (MethodDocs [] (MethodVal "names" "[String]"))+      (methodListS   methods)   ]
+ src/Network/MessagePack/Rpc.hs view
@@ -0,0 +1,105 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies          #-}+module Network.MessagePack.Rpc+  ( I.Returns+  , I.Doc (..)+  , method+  , rpc+  , docs+  , stubs, Rpc, RpcT (local)+  , stubsIO, RpcIO, RpcIOT (localIO)+  ) where++import           Control.Monad.Catch                    (MonadThrow)++import qualified Network.MessagePack.Client             as Client+import qualified Network.MessagePack.Interface.Internal as I+import qualified Network.MessagePack.Server             as Server+++class RpcService rpc where+  type ClientMonad rpc :: * -> *+  type ServerMonad rpc :: * -> *+  type F rpc+  rpc    :: rpc -> I.ClientType (ClientMonad rpc) (F rpc)+  method :: rpc -> Server.Method (ServerMonad rpc)+  docs   :: rpc -> (String, I.Doc (F rpc))+++--------------------------------------------------------------------------------+--+-- :: Non-IO RPCs+--+--------------------------------------------------------------------------------++type Rpc f = RpcT IO IO f++data RpcT mc ms f = RpcT+  { rpcPure    :: I.ClientType mc f+  , local      :: I.HaskellType f+  , methodPure :: Server.Method ms+  , intfPure   :: I.Interface f+  }++instance RpcService (RpcT mc ms f) where+  type ClientMonad (RpcT mc ms f) = mc+  type ServerMonad (RpcT mc ms f) = ms+  type F (RpcT mc ms f) = f+  rpc    = rpcPure+  method = methodPure+  docs r = (Server.methodName $ method r, I.docs $ intfPure r)+++stubs+  :: ( Client.RpcType (I.ClientType mc f)+     , Server.MethodType ms (I.ServerType ms f)+     , I.IsReturnType ms f+     , I.IsDocType f+     , MonadThrow ms+     )+  => String -> I.Doc f -> I.HaskellType f -> RpcT mc ms f+stubs n doc f = RpcT c f m i+  where+    c = Client.call n+    m = I.method i f+    i = I.interface n doc+++--------------------------------------------------------------------------------+--+-- :: IO RPCs+--+--------------------------------------------------------------------------------++type RpcIO f = RpcIOT IO IO f++data RpcIOT mc ms f = RpcIOT+  { rpcIO    :: I.ClientType mc f+  , localIO  :: I.HaskellTypeIO f+  , methodIO :: Server.Method ms+  , intfIO   :: I.Interface f+  }++instance RpcService (RpcIOT mc ms f) where+  type ClientMonad (RpcIOT mc ms f) = mc+  type ServerMonad (RpcIOT mc ms f) = ms+  type F (RpcIOT mc ms f) = f+  rpc    = rpcIO+  method = methodIO+  docs r = (Server.methodName $ method r, I.docs $ intfIO r)+++stubsIO+  :: ( Client.RpcType (I.ClientType mc f)+     , Server.MethodType ms (I.ServerTypeIO ms f)+     , I.IsReturnTypeIO ms f+     , I.IsDocType f+     , MonadThrow ms+     )+  => String -> I.Doc f -> I.HaskellTypeIO f -> RpcIOT mc ms f+stubsIO n doc f = RpcIOT c f m i+  where+    c = Client.call n+    m = I.methodIO i f+    i = I.interface n doc
src/Network/MessagePack/Server.hs view
@@ -4,11 +4,15 @@   -- * RPC method types     Method   , MethodType (..)+  , MethodDocs (..)+  , MethodVal (..)   , ServerT (..)   , Server    -- * Build a method   , method+  , methodName+  , methodDocs    -- * Start RPC server   , serve
src/Network/MessagePack/Server/Basic.hs view
@@ -34,6 +34,8 @@ module Network.MessagePack.Server.Basic (   -- * RPC method types     Method+  , MethodVal (..)+  , MethodDocs (..)   , MethodType (..)   , ServerT (..)   , Server@@ -43,6 +45,7 @@    -- * Get the method name   , methodName+  , methodDocs    -- * Start RPC server   , serve@@ -74,9 +77,22 @@  import           Network.MessagePack.Types +data MethodVal = MethodVal+  { valName :: String+  , valType :: String+  }+  deriving (Show)++data MethodDocs = MethodDocs+  { methodArgs :: [MethodVal]+  , methodRetv :: MethodVal+  }+  deriving (Show)+ -- ^ MessagePack RPC method data Method m = Method   { methodName :: String+  , methodDocs :: MethodDocs   , methodBody :: [Object] -> m Object   } @@ -116,9 +132,10 @@ method   :: MethodType m f   => String   -- ^ Method name+  -> MethodDocs   -> f        -- ^ Method body   -> Method m-method name body = Method name $ toBody name body+method name docs body = Method name docs $ toBody name body   processRequests