summaryrefslogtreecommitdiff
path: root/src/Remote/KRPC.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Remote/KRPC.hs')
-rw-r--r--src/Remote/KRPC.hs48
1 files changed, 25 insertions, 23 deletions
diff --git a/src/Remote/KRPC.hs b/src/Remote/KRPC.hs
index a542f0b4..5c1aadd6 100644
--- a/src/Remote/KRPC.hs
+++ b/src/Remote/KRPC.hs
@@ -21,6 +21,7 @@ module Remote.KRPC
21 , (==>), server 21 , (==>), server
22 ) where 22 ) where
23 23
24import Control.Applicative
24import Control.Exception 25import Control.Exception
25import Control.Monad.Trans.Control 26import Control.Monad.Trans.Control
26import Control.Monad.IO.Class 27import Control.Monad.IO.Class
@@ -39,31 +40,39 @@ data RPCException = RPCException KError
39 deriving (Show, Eq, Typeable) 40 deriving (Show, Eq, Typeable)
40 41
41instance Exception RPCException 42instance Exception RPCException
43type RemoteAddr = KRemoteAddr
42 44
45extractArgs :: BEncodable arg
46 => [ParamName] -> Map ParamName BEncode -> Result arg
47extractArgs as d = fromBEncode =<<
48 case as of
49 [] -> Right (BList [])
50 [x] -> f x
51 xs -> BList <$> mapM f xs
52 where
53 f x = maybe (Left ("not found key " ++ BC.unpack x)) Right
54 (M.lookup x d)
55{-# INLINE extractArgs #-}
43 56
44type RemoteAddr = KRemoteAddr 57injectVals :: BEncodable arg => [ParamName] -> arg -> [(ParamName, BEncode)]
58injectVals [] (toBEncode -> BList []) = []
59injectVals [p] (toBEncode -> arg) = [(p, arg)]
60injectVals ps (toBEncode -> BList as) = L.zip ps as
61injectVals _ _ = error "KRPC.injectVals: impossible"
62{-# INLINE injectVals #-}
45 63
46 64
47queryCall :: BEncodable param 65queryCall :: BEncodable param
48 => Extractable param
49 => KRemote -> KRemoteAddr 66 => KRemote -> KRemoteAddr
50 -> Method param result -> param -> IO () 67 -> Method param result -> param -> IO ()
51queryCall sock addr m arg = sendMessage q addr sock 68queryCall sock addr m arg = sendMessage q addr sock
52 where 69 where
53 q = kquery (methodName m) (mkVals (methodParams m) (injector arg)) 70 q = kquery (methodName m) (injectVals (methodParams m) arg)
54 mkVals = L.zip
55 71
56 72
57extractArgs :: [ParamName] -> Map ParamName BEncode -> Result [BEncode]
58extractArgs as d = mapM f as
59 where
60 f x | Just y <- M.lookup x d = return y
61 | otherwise = Left ("not found key " ++ BC.unpack x)
62{-# INLINE extractArgs #-}
63 73
64-- TODO check scheme 74-- TODO check scheme
65getResult :: BEncodable result 75getResult :: BEncodable result
66 => Extractable result
67 => KRemote -> KRemoteAddr 76 => KRemote -> KRemoteAddr
68 -> Method param result -> IO result 77 -> Method param result -> IO result
69getResult sock addr m = do 78getResult sock addr m = do
@@ -71,7 +80,7 @@ getResult sock addr m = do
71 case resp of 80 case resp of
72 Left e -> throw (RPCException e) 81 Left e -> throw (RPCException e)
73 Right (respVals -> dict) -> do 82 Right (respVals -> dict) -> do
74 case extractArgs (methodVals m) dict >>= extractor of 83 case extractArgs (methodVals m) dict of
75 Right vals -> return vals 84 Right vals -> return vals
76 Left e -> throw (RPCException (ProtocolError (BC.pack e))) 85 Left e -> throw (RPCException (ProtocolError (BC.pack e)))
77 86
@@ -81,7 +90,6 @@ getResult sock addr m = do
81-- 90--
82call :: (MonadBaseControl IO host, MonadIO host) 91call :: (MonadBaseControl IO host, MonadIO host)
83 => (BEncodable param, BEncodable result) 92 => (BEncodable param, BEncodable result)
84 => (Extractable param, Extractable result)
85 => RemoteAddr 93 => RemoteAddr
86 -> Method param result 94 -> Method param result
87 -> param 95 -> param
@@ -96,7 +104,6 @@ newtype Async result = Async { waitResult :: IO result }
96-- TODO document errorneous usage 104-- TODO document errorneous usage
97async :: MonadIO host 105async :: MonadIO host
98 => (BEncodable param, BEncodable result) 106 => (BEncodable param, BEncodable result)
99 => (Extractable param, Extractable result)
100 => RemoteAddr 107 => RemoteAddr
101 -> Method param result 108 -> Method param result
102 -> param 109 -> param
@@ -119,8 +126,7 @@ type MethodHandler remote = (MethodName, HandlerBody remote)
119 126
120-- we can safely erase types in (==>) 127-- we can safely erase types in (==>)
121(==>) :: forall (remote :: * -> *) (param :: *) (result :: *). 128(==>) :: forall (remote :: * -> *) (param :: *) (result :: *).
122-- (BEncodable param, BEncodable result) 129 (BEncodable param, BEncodable result)
123 (Extractable param, Extractable result)
124 => Monad remote 130 => Monad remote
125 => Method param result 131 => Method param result
126 -> (param -> remote result) 132 -> (param -> remote result)
@@ -130,14 +136,13 @@ m ==> body = (methodName m, newbody)
130 where 136 where
131 {-# INLINE newbody #-} 137 {-# INLINE newbody #-}
132 newbody q = 138 newbody q =
133 case extractArgs (methodParams m) (queryArgs q) >>= extractor of 139 case extractArgs (methodParams m) (queryArgs q) of
134 Left e -> return (Left (ProtocolError (BC.pack e))) 140 Left e -> return (Left (ProtocolError (BC.pack e)))
135 Right a -> do 141 Right a -> do
136 r <- body a 142 r <- body a
137 return (Right (kresponse (mkVals (methodVals m) (injector r)))) 143 return (Right (kresponse (injectVals (methodVals m) r)))
138 144
139 mkVals :: [ValName] -> [BEncode] -> [(ValName, BEncode)] 145infix 1 ==>
140 mkVals = L.zip
141 146
142-- TODO: allow forkIO 147-- TODO: allow forkIO
143server :: (MonadBaseControl IO remote, MonadIO remote) 148server :: (MonadBaseControl IO remote, MonadIO remote)
@@ -153,6 +158,3 @@ server servport handlers = do
153 handlerMap = M.fromList handlers 158 handlerMap = M.fromList handlers
154 dispatch s = M.lookup s handlerMap 159 dispatch s = M.lookup s handlerMap
155 invoke m q = m q 160 invoke m q = m q
156
157 bimap f _ (Left x) = Left (f x)
158 bimap _ g (Right x) = Right (g x) \ No newline at end of file