summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Remote/KRPC.hs48
-rw-r--r--src/Remote/KRPC/Method.hs30
2 files changed, 25 insertions, 53 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
diff --git a/src/Remote/KRPC/Method.hs b/src/Remote/KRPC/Method.hs
index d0c8e89a..4283256b 100644
--- a/src/Remote/KRPC/Method.hs
+++ b/src/Remote/KRPC/Method.hs
@@ -16,9 +16,6 @@ module Remote.KRPC.Method
16 16
17 -- * Predefined methods 17 -- * Predefined methods
18 , idM 18 , idM
19
20 -- * Internal
21 , Extractable(..)
22 ) where 19 ) where
23 20
24import Control.Applicative 21import Control.Applicative
@@ -69,30 +66,3 @@ idM = method "id" ["x"] ["y"]
69method :: MethodName -> [ParamName] -> [ValName] -> Method param result 66method :: MethodName -> [ParamName] -> [ValName] -> Method param result
70method = Method 67method = Method
71{-# INLINE method #-} 68{-# INLINE method #-}
72
73
74
75class Extractable a where
76 injector :: a -> [BEncode]
77 extractor :: [BEncode] -> Result a
78
79instance (BEncodable a, BEncodable b) => Extractable (a, b) where
80 {- SPECIALIZE instance (BEncodable a, BEncodable b) => Extractable (a, b) -}
81 injector (a, b) = [toBEncode a, toBEncode b]
82 {-# INLINE injector #-}
83
84 extractor [a, b] = (,) <$> fromBEncode a <*> fromBEncode b
85 extractor _ = decodingError "unable to match pair"
86 {-# INLINE extractor #-}
87
88{-
89instance BEncodable a => Extractable a where
90 {-# SPECIALIZE instance BEncodable a => Extractable a #-}
91
92 injector x = [toBEncode x]
93 {-# INLINE injector #-}
94
95 extractor [x] = fromBEncode x
96 extractor _ = decodingError "unable to match single value"
97 {-# INLINE extractor #-}
98-} \ No newline at end of file