Skip to content

Commit ac19597

Browse files
committed
Support aeson-2.0.
1 parent 5a8844e commit ac19597

File tree

4 files changed

+53
-11
lines changed

4 files changed

+53
-11
lines changed

json-rpc-server.cabal

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ flag demo
3737
library
3838
exposed-modules: Network.JsonRpc.Server
3939
other-modules: Network.JsonRpc.Types
40-
build-depends: base >=4.3 && <4.15,
41-
aeson >=0.6 && <1.6,
40+
build-depends: base >=4.3 && <4.16,
41+
aeson (>=0.6 && <1.6) || (>=2.1 && <2.2),
4242
deepseq >= 1.1 && <1.5,
4343
bytestring >=0.9 && <0.11,
4444
mtl >=2.2.1 && <2.3,

src/Network/JsonRpc/Types.hs

+33-5
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,22 @@ module Network.JsonRpc.Types ( RpcResult
2020
, rpcErrorWithData) where
2121

2222
import Data.Maybe (catMaybes)
23-
import Data.Text (Text, append, unpack)
23+
import Data.Text (Text)
24+
#if ! MIN_VERSION_aeson(2,0,0)
25+
import Data.Text (unpack)
26+
#endif
2427
import qualified Data.Aeson as A
28+
#if MIN_VERSION_aeson(2,0,0)
29+
import qualified Data.Aeson.Key as A
30+
#endif
2531
import Data.Aeson ((.=), (.:), (.:?), (.!=))
2632
import Data.Aeson.Types (emptyObject)
2733
import qualified Data.Vector as V
34+
#if MIN_VERSION_aeson(2,0,0)
35+
import qualified Data.Aeson.KeyMap as KeyMap
36+
#else
2837
import qualified Data.HashMap.Strict as H
38+
#endif
2939
import Control.DeepSeq (NFData, rnf)
3040
import Control.Monad (when)
3141
import Control.Monad.Except (ExceptT (..), throwError)
@@ -68,22 +78,22 @@ instance (A.FromJSON a, MethodParams f p m r) => MethodParams (a -> f) (a :+: p)
6878
ExceptT (return arg) >>= \a -> _apply (f a) ps nextArgs
6979
where
7080
arg = maybe (paramDefault param) (parseArg name) lookupValue
71-
lookupValue = either (H.lookup name) (V.!? 0) args
81+
lookupValue = either (lookupInObject name) (V.!? 0) args
7282
nextArgs = V.drop 1 <$> args
7383
name = paramName param
7484

7585
parseArg :: A.FromJSON r => Text -> A.Value -> Either RpcError r
7686
parseArg name val = case A.fromJSON val of
7787
A.Error msg -> throwError $ argTypeError msg
7888
A.Success x -> return x
79-
where argTypeError = rpcErrorWithData (-32602) $ "Wrong type for argument: " `append` name
89+
where argTypeError = rpcErrorWithData (-32602) $ "Wrong type for argument: " <> name
8090

8191
paramDefault :: Parameter a -> Either RpcError a
8292
paramDefault (Optional _ d) = Right d
8393
paramDefault (Required name) = Left $ missingArgError name
8494

8595
missingArgError :: Text -> RpcError
86-
missingArgError name = rpcError (-32602) $ "Cannot find required argument: " `append` name
96+
missingArgError name = rpcError (-32602) $ "Cannot find required argument: " <> name
8797

8898
paramName :: Parameter a -> Text
8999
paramName (Optional n _) = n
@@ -106,7 +116,7 @@ instance A.FromJSON Request where
106116
parseParams (A.Array ar) = return $ Right ar
107117
parseParams _ = empty
108118
checkVersion ver = when (ver /= jsonRpcVersion) $
109-
fail $ "Wrong JSON-RPC version: " ++ unpack ver
119+
fail $ "Wrong JSON-RPC version: " ++ unpackKey ver
110120
-- (.:?) parses Null value as Nothing so parseId needs
111121
-- to use both (.:?) and (.:) to handle all cases
112122
parseId = x .:? idKey >>= \optional ->
@@ -180,7 +190,25 @@ rpcError code msg = RpcError code msg Nothing
180190
rpcErrorWithData :: A.ToJSON a => Int -> Text -> a -> RpcError
181191
rpcErrorWithData code msg errorData = RpcError code msg $ Just $ A.toJSON errorData
182192

193+
#if MIN_VERSION_aeson(2,0,0)
194+
jsonRpcVersion, versionKey, idKey :: A.Key
195+
#else
183196
jsonRpcVersion, versionKey, idKey :: Text
197+
#endif
184198
jsonRpcVersion = "2.0"
185199
versionKey = "jsonrpc"
186200
idKey = "id"
201+
202+
#if MIN_VERSION_aeson(2,0,0)
203+
unpackKey :: A.Key -> String
204+
unpackKey = A.toString
205+
206+
lookupInObject :: Text -> KeyMap.KeyMap A.Value -> Maybe A.Value
207+
lookupInObject key = KeyMap.lookup (A.fromText key)
208+
#else
209+
unpackKey :: Text -> String
210+
unpackKey = unpack
211+
212+
lookupInObject :: Text -> H.HashMap Text A.Value -> Maybe A.Value
213+
lookupInObject = H.lookup
214+
#endif

tests/Internal.hs

+12-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ module Internal ( request
1818

1919
import qualified Data.Aeson as A
2020
import Data.Aeson ((.=))
21+
#if MIN_VERSION_aeson(2,0,0)
22+
import qualified Data.Aeson.KeyMap as H
23+
#else
2124
import qualified Data.HashMap.Strict as H
25+
#endif
2226
import Data.Maybe (catMaybes)
2327
import qualified Data.Vector as V
2428
import Data.Text (Text)
@@ -44,7 +48,7 @@ defaultRq :: A.Value
4448
defaultRq = request (Just defaultId) "subtract" args
4549
where args = Just $ A.object ["x" .= A.Number 1, "y" .= A.Number 2]
4650

47-
response :: A.Value -> Text -> A.Value -> A.Value
51+
response :: A.Value -> Key -> A.Value -> A.Value
4852
response i key res = A.object ["id" .= i, key .= res, "jsonrpc" .= A.String "2.0"]
4953

5054
defaultRsp :: A.Value
@@ -78,7 +82,7 @@ version rq = insert rq "jsonrpc"
7882
result :: A.Value -> A.Value -> A.Value
7983
result rsp = insert rsp "result" . Just
8084

81-
insert :: A.Value -> Text -> Maybe A.Value -> A.Value
85+
insert :: A.Value -> Key -> Maybe A.Value -> A.Value
8286
insert (A.Object obj) key Nothing = A.Object $ H.delete key obj
8387
insert (A.Object obj) key (Just val) = A.Object $ H.insert key val obj
8488
insert v _ _ = v
@@ -88,3 +92,9 @@ defaultId = A.Number 3
8892

8993
defaultResult :: A.Value
9094
defaultResult = A.Number (-1)
95+
96+
#if MIN_VERSION_aeson(2,0,0)
97+
type Key = A.Key
98+
#else
99+
type Key = Text
100+
#endif

tests/TestSuite.hs

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ import Data.Function (on)
1616
import qualified Data.Aeson as A
1717
import Data.Aeson ((.=))
1818
import qualified Data.Aeson.Types as A
19+
#if MIN_VERSION_aeson(2,0,0)
20+
import qualified Data.Aeson.KeyMap as H
21+
#else
1922
import qualified Data.HashMap.Strict as H
23+
#endif
2024
import qualified Data.ByteString.Lazy.Char8 as LB
2125
import Control.Monad.Trans (liftIO)
2226
import Control.Monad.State (State, runState, lift, modify)
23-
import Control.Monad.Identity (Identity, runIdentity)
27+
import Control.Monad.Identity (Identity(..), runIdentity)
2428
import Test.HUnit hiding (State, Test)
2529
import Test.Framework (defaultMain, Test)
2630
import Test.Framework.Providers.HUnit (testCase)
@@ -185,7 +189,7 @@ getTimeMethod = S.toMethod "get_time_seconds" getTestTime ()
185189
getTestTime = liftIO $ return 100
186190

187191
removeErrMsg :: A.Value -> A.Value
188-
removeErrMsg (A.Object rsp) = A.Object $ H.adjust removeMsg "error" rsp
192+
removeErrMsg (A.Object rsp) = A.Object $ runIdentity $ H.alterF (Identity . fmap removeMsg) "error" rsp
189193
where removeMsg (A.Object err) = A.Object $ H.insert "message" "" $ H.delete "data" err
190194
removeMsg v = v
191195
removeErrMsg (A.Array rsps) = A.Array $ removeErrMsg `V.map` rsps

0 commit comments

Comments
 (0)