-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJsonRpcClient.hs
83 lines (75 loc) · 3.57 KB
/
JsonRpcClient.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{-# LANGUAGE OverloadedStrings #-}
module JsonRpcClient
( JsonRpcVersion(JsonRpcV1, JsonRpcV2)
, JsonRpcRequest(..)
, JsonRpcNotification
, JsonRpcError(..)
, parseJsonRpc
) where
import Data.ByteString.Lazy (ByteString)
import Control.Applicative ((<$>), (<*>), empty)
import Data.Either
import Data.Aeson
data JsonRpcVersion = JsonRpcV1 | JsonRpcV2
deriving (Show)
data JsonRpcRequest = JsonRpcRequest { jrpcVersion :: JsonRpcVersion
, jrpcReqMethod :: ByteString
, jrpcReqParams :: [ByteString]
, jrpcReqId :: Value
} deriving (Show)
instance ToJSON JsonRpcRequest where
toJSON (JsonRpcRequest version method params id) =
let l = [ "method" .= method, "params" .= params, "id" .= id ]
in case version of
JsonRpcV1 -> object l
JsonRpcV2 -> object $ ("jsonrpc" .= toJSON ("2.0" :: ByteString)):l
data JsonRpcNotification = JsonRpcNotification
{ jrpcNtfVersion :: JsonRpcVersion
, jrpcNtfMethod :: ByteString
, jrpcNtfParams :: [ByteString]
} deriving (Show)
instance ToJSON JsonRpcNotification where
toJSON (JsonRpcNotification version method params) =
let l = [ "method" .= method, "params" .= params ]
in case version of
JsonRpcV1 -> object l
JsonRpcV2 -> object $ ("jsonrpc" .= toJSON ("2.0" :: ByteString)):l
data JsonRpcError = JsonRpcError { jrpcErrCode :: Int
, jrpcErrMessage :: ByteString
, jrpcErrData :: Maybe Value
} deriving (Show)
instance FromJSON JsonRpcError where
parseJSON (Object o) = JsonRpcError
<$> o .: "code"
<*> o .: "message"
<*> o .:? "data"
parseJSON x = return $ JsonRpcError
(-32600)
"Unparseable error object"
(Just (toJSON x))
data JsonRpcResponse = JsonRpcResponse { jrpcRspResult :: Maybe Value
, jrpcRspError :: JsonRpcError
, jrpcRspId :: Value
} deriving (Show)
instance FromJSON JsonRpcResponse where
parseJSON (Object o) = JsonRpcResponse
<$> o .:? "result"
<*> o .: "error"
<*> o .: "id"
parseJSON x = return $ JsonRpcResponse
Nothing
(JsonRpcError
(-32700)
"Unparseable response object"
(Just (toJSON x))
)
(String "n/a")
parseJsonRpc :: (FromJSON a) => ByteString -> Either JsonRpcError a
parseJsonRpc s = case (decode s :: Maybe JsonRpcResponse) of
Just (JsonRpcResponse result error id) ->
case result of
Just v -> case fromJSON v of
Success a -> Right a
Error s -> Left $ JsonRpcError (-32900) "Unparseable result" (Just v)
Nothing -> Left error
Nothing -> Left $ JsonRpcError (-32800) "Unparseable response" (Just (toJSON s))