summaryrefslogtreecommitdiff
path: root/src/Remote
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-05-12 01:07:34 +0400
committerSam T <pxqr.sta@gmail.com>2013-05-12 01:07:34 +0400
commitfd62eb70fe87b471d29cb994a60ad88f58b33ca9 (patch)
treeed8c7d69f10c1b874cc03c7d6e5064fb81b94482 /src/Remote
parent7614ed760e137219fb4e36288abf1e78eacb2266 (diff)
~ Prepare to scheme check.
Diffstat (limited to 'src/Remote')
-rw-r--r--src/Remote/KRPC.hs54
-rw-r--r--src/Remote/KRPC/Method.hs22
-rw-r--r--src/Remote/KRPC/Protocol.hs17
3 files changed, 64 insertions, 29 deletions
diff --git a/src/Remote/KRPC.hs b/src/Remote/KRPC.hs
index 8f2027f2..22dbf3aa 100644
--- a/src/Remote/KRPC.hs
+++ b/src/Remote/KRPC.hs
@@ -10,6 +10,7 @@
10{-# LANGUAGE OverloadedStrings #-} 10{-# LANGUAGE OverloadedStrings #-}
11{-# LANGUAGE FlexibleContexts, DeriveDataTypeable #-} 11{-# LANGUAGE FlexibleContexts, DeriveDataTypeable #-}
12{-# LANGUAGE ExplicitForAll, KindSignatures #-} 12{-# LANGUAGE ExplicitForAll, KindSignatures #-}
13{-# LANGUAGE ViewPatterns #-}
13module Remote.KRPC 14module Remote.KRPC
14 ( module Remote.KRPC.Method, RemoteAddr 15 ( module Remote.KRPC.Method, RemoteAddr
15 16
@@ -17,7 +18,7 @@ module Remote.KRPC
17 , call, async, await 18 , call, async, await
18 19
19 -- * Server 20 -- * Server
20 , server 21 , (==>), server
21 ) where 22 ) where
22 23
23import Control.Exception 24import Control.Exception
@@ -27,6 +28,7 @@ import Control.Monad.IO.Class
27import Data.BEncode 28import Data.BEncode
28import Data.List as L 29import Data.List as L
29import Data.Map as M 30import Data.Map as M
31import Data.Set as S
30import Data.Text as T 32import Data.Text as T
31import Data.Typeable 33import Data.Typeable
32import Network 34import Network
@@ -51,6 +53,7 @@ queryCall sock addr m arg = sendMessage q addr sock
51 where 53 where
52 q = kquery (L.head (methodName m)) [(L.head (methodParams m), toBEncode arg)] 54 q = kquery (L.head (methodName m)) [(L.head (methodParams m), toBEncode arg)]
53 55
56-- TODO check scheme
54getResult :: BEncodable result 57getResult :: BEncodable result
55 => KRemote -> KRemoteAddr 58 => KRemote -> KRemoteAddr
56 -> Method param result -> IO result 59 -> Method param result -> IO result
@@ -58,7 +61,7 @@ getResult sock addr m = do
58 resp <- recvResponse addr sock 61 resp <- recvResponse addr sock
59 case resp of 62 case resp of
60 Left e -> throw (RPCException e) 63 Left e -> throw (RPCException e)
61 Right (KResponse dict) -> do 64 Right (respVals -> dict) -> do
62 let valName = L.head (methodVals m) 65 let valName = L.head (methodVals m)
63 case M.lookup valName dict of 66 case M.lookup valName dict of
64 Just val | Right res <- fromBEncode val -> return res 67 Just val | Right res <- fromBEncode val -> return res
@@ -102,10 +105,10 @@ async addr m arg = do
102await :: MonadIO host => Async result -> host result 105await :: MonadIO host => Async result -> host result
103await = liftIO . waitResult 106await = liftIO . waitResult
104 107
105-- TODO better name 108type HandlerBody remote = (BEncode -> remote (Result BEncode), KResponseScheme)
106type MHandler remote = ( Method BEncode (Result BEncode) 109
107 , BEncode -> remote (Result BEncode) 110type MethodHandler remote = (KQueryScheme, HandlerBody remote)
108 ) 111
109 112
110-- we can safely erase types in (==>) 113-- we can safely erase types in (==>)
111(==>) :: forall (remote :: * -> *) (param :: *) (result :: *). 114(==>) :: forall (remote :: * -> *) (param :: *) (result :: *).
@@ -113,8 +116,8 @@ type MHandler remote = ( Method BEncode (Result BEncode)
113 => Monad remote 116 => Monad remote
114 => Method param result 117 => Method param result
115 -> (param -> remote result) 118 -> (param -> remote result)
116 -> MHandler remote 119 -> MethodHandler remote
117m ==> body = undefined 120m ==> body = (methodQueryScheme m, (newbody, methodRespScheme m))
118 where 121 where
119 newbody x = case fromBEncode x of 122 newbody x = case fromBEncode x of
120 Right a -> liftM (Right . toBEncode) (body a) 123 Right a -> liftM (Right . toBEncode) (body a)
@@ -125,15 +128,28 @@ m ==> body = undefined
125-- TODO: allow overloading 128-- TODO: allow overloading
126server :: (MonadBaseControl IO remote, MonadIO remote) 129server :: (MonadBaseControl IO remote, MonadIO remote)
127 => PortNumber 130 => PortNumber
128 -> [MHandler remote] 131 -> [MethodHandler remote]
129 -> remote () 132 -> remote ()
130server servport ms = remoteServer servport $ \_ q -> do 133server servport handlers = do
131 let name = queryMethod q 134 remoteServer servport $ \_ q -> do
132 let args = undefined -- queryArgs q 135 case dispatch (scheme q) of
133 let m = L.head ms 136 Nothing -> return (Left (MethodUnknown "method"))
134 res <- undefined -- methodBody m (snd (L.head (M.toList args))) 137 Just (m, rsc) -> do
135 case res of 138 let arg = snd (L.head (M.toList (queryArgs q)))
136 Left r -> return (Left (ProtocolError (T.pack r))) 139
137 Right r -> do 140 res <- invoke m arg
138 let retName = undefined -- L.head (methodVals m) 141 let valName = L.head (S.toList (rscVals rsc))
139 return (Right (kresponse [(retName, r)])) 142 return $ bimap (ProtocolError . T.pack)
143 (kresponse . return . (,) valName) res
144 where
145 handlerMap = M.fromList handlers
146
147-- dispatch :: KQueryScheme -> MethodHandler remote
148 dispatch s | Just m <- M.lookup s handlerMap = return m
149 | otherwise = Nothing
150
151-- invoke :: MethodHandler remote -> BEncode -> remote BEncode
152 invoke m args = m args
153
154 bimap f _ (Left x) = Left (f x)
155 bimap _ g (Right x) = Right (g x) \ No newline at end of file
diff --git a/src/Remote/KRPC/Method.hs b/src/Remote/KRPC/Method.hs
index 3c757d07..420ceacf 100644
--- a/src/Remote/KRPC/Method.hs
+++ b/src/Remote/KRPC/Method.hs
@@ -1,6 +1,14 @@
1-- |
2-- Copyright : (c) Sam T. 2013
3-- License : MIT
4-- Maintainer : pxqr.sta@gmail.com
5-- Stability : experimental
6-- Portability : portable
7--
1{-# LANGUAGE OverloadedStrings #-} 8{-# LANGUAGE OverloadedStrings #-}
2module Remote.KRPC.Method 9module Remote.KRPC.Method
3 ( Method(methodName, methodParams, methodVals) 10 ( Method(methodName, methodParams, methodVals)
11 , methodQueryScheme, methodRespScheme
4 12
5 -- * Construction 13 -- * Construction
6 , method 14 , method
@@ -10,13 +18,16 @@ module Remote.KRPC.Method
10 ) where 18 ) where
11 19
12import Prelude hiding ((.), id) 20import Prelude hiding ((.), id)
21import Control.Applicative
13import Control.Category 22import Control.Category
14import Control.Monad 23import Control.Monad
24import Data.ByteString as B
25import Data.List as L
26import Data.Set as S
15 27
16import Remote.KRPC.Protocol 28import Remote.KRPC.Protocol
17 29
18 30
19
20-- | The 31-- | The
21-- 32--
22-- * argument: type of method parameter 33-- * argument: type of method parameter
@@ -44,6 +55,15 @@ instance Category Method where
44 (.) = composeM 55 (.) = composeM
45 {-# INLINE (.) #-} 56 {-# INLINE (.) #-}
46 57
58methodQueryScheme :: Method a b -> KQueryScheme
59methodQueryScheme = KQueryScheme <$> B.intercalate "." . methodName
60 <*> S.fromList . methodParams
61{-# INLINE methodQueryScheme #-}
62
63
64methodRespScheme :: Method a b -> KResponseScheme
65methodRespScheme = KResponseScheme . S.fromList . methodVals
66{-# INLINE methodRespScheme #-}
47 67
48-- TODO ppMethod 68-- TODO ppMethod
49 69
diff --git a/src/Remote/KRPC/Protocol.hs b/src/Remote/KRPC/Protocol.hs
index e7fbea11..625aba25 100644
--- a/src/Remote/KRPC/Protocol.hs
+++ b/src/Remote/KRPC/Protocol.hs
@@ -24,12 +24,12 @@ module Remote.KRPC.Protocol
24 , KError(..), errorCode, mkKError 24 , KError(..), errorCode, mkKError
25 25
26 -- * Query 26 -- * Query
27 , KQuery(queryMethod, queryParams), MethodName, ParamName, kquery 27 , KQuery(queryMethod, queryArgs), MethodName, ParamName, kquery
28 , KQueryScheme(qscMethod, qscParams) 28 , KQueryScheme(KQueryScheme, qscMethod, qscParams)
29 29
30 -- * Response 30 -- * Response
31 , KResponse(respVals), ValName, kresponse 31 , KResponse(respVals), ValName, kresponse
32 , KResponseScheme(rscVals) 32 , KResponseScheme(KResponseScheme, rscVals)
33 33
34 , sendMessage, recvResponse 34 , sendMessage, recvResponse
35 35
@@ -46,12 +46,14 @@ import Control.Exception.Lifted
46import Control.Monad 46import Control.Monad
47import Control.Monad.IO.Class 47import Control.Monad.IO.Class
48import Control.Monad.Trans.Control 48import Control.Monad.Trans.Control
49
49import Data.BEncode 50import Data.BEncode
50import Data.ByteString as B 51import Data.ByteString as B
51import qualified Data.ByteString.Lazy as LB 52import qualified Data.ByteString.Lazy as LB
52import Data.Map as M 53import Data.Map as M
53import Data.Set as S 54import Data.Set as S
54import Data.Text as T 55import Data.Text as T
56
55import Network.Socket hiding (recvFrom) 57import Network.Socket hiding (recvFrom)
56import Network.Socket.ByteString 58import Network.Socket.ByteString
57 59
@@ -134,7 +136,7 @@ type ParamName = ByteString
134-- TODO document that it is and how transferred 136-- TODO document that it is and how transferred
135data KQuery = KQuery { 137data KQuery = KQuery {
136 queryMethod :: MethodName 138 queryMethod :: MethodName
137 , queryParams :: Map ParamName BEncode 139 , queryArgs :: Map ParamName BEncode
138 } deriving (Show, Read, Eq, Ord) 140 } deriving (Show, Read, Eq, Ord)
139 141
140instance BEncodable KQuery where 142instance BEncodable KQuery where
@@ -160,12 +162,9 @@ data KQueryScheme = KQueryScheme {
160 , qscParams :: Set ParamName 162 , qscParams :: Set ParamName
161 } deriving (Show, Read, Eq, Ord) 163 } deriving (Show, Read, Eq, Ord)
162 164
163domen :: Map a b -> Set a
164domen = error "scheme.domen"
165
166instance KMessage KQuery KQueryScheme where 165instance KMessage KQuery KQueryScheme where
167 {-# SPECIALIZE instance KMessage KQuery KQueryScheme #-} 166 {-# SPECIALIZE instance KMessage KQuery KQueryScheme #-}
168 scheme q = KQueryScheme (queryMethod q) (domen (queryParams q)) 167 scheme q = KQueryScheme (queryMethod q) (M.keysSet (queryArgs q))
169 {-# INLINE scheme #-} 168 {-# INLINE scheme #-}
170 169
171type ValName = ByteString 170type ValName = ByteString
@@ -198,7 +197,7 @@ newtype KResponseScheme = KResponseScheme {
198 197
199instance KMessage KResponse KResponseScheme where 198instance KMessage KResponse KResponseScheme where
200 {-# SPECIALIZE instance KMessage KResponse KResponseScheme #-} 199 {-# SPECIALIZE instance KMessage KResponse KResponseScheme #-}
201 scheme = KResponseScheme . domen . respVals 200 scheme = KResponseScheme . keysSet . respVals
202 {-# INLINE scheme #-} 201 {-# INLINE scheme #-}
203 202
204 203