git.iko.soy/typeable/rollbar-hs
on master help sign in
11 files changed+95−75
since splitsnapshots
unifiedsplit
package.yaml−46 rollbar-hs.cabal+21−19 src/Rollbar/Aeson.hs+22 src/Rollbar/Item.hs+8 src/Rollbar/Item/Body.hs+10−4 src/Rollbar/Item/MissingHeaders.hs+8−3 src/Rollbar/Item/Request.hs+12−2 src/Rollbar/Item/Server.hs+5 stack.yaml+6 test/Rollbar/Item/Data/Test.hs+1−1 test/Rollbar/Item/MissingHeaders/Test.hs+2
package.yamldeleted−46
@@ -1,46 +0,0 @@
1−author: Hardy Jones
2−category: Web
3−copyright: 2018 Hardy Jones
4−description: |
5− Provides a type-safe encoding of the Rollbar API.
6− Also provides functions to communicate with the Rollbar API.
7−extra-source-files:
8− - CHANGELOG.md
9− - README.md
10−github: joneshf/rollbar-hs
11−library:
12− dependencies:
13− - aeson >= 1.0 && < 1.5
14− - base >= 4.9 && < 5
15− - bytestring >= 0.10 && < 0.11
16− - case-insensitive >= 1.2 && < 1.3
17− - hostname >= 1.0 && < 1.1
18− - http-client >= 0.5 && < 0.6
19− - http-conduit >= 2.2 && < 2.4
20− - http-types >= 0.9 && < 0.13
21− - network >= 2.6 && < 2.9
22− - text >= 1.2 && < 1.3
23− - time >= 1.6 && < 1.9
24− - unordered-containers >= 0.2 && < 0.3
25− - uuid >= 1.3 && < 1.4
26− source-dirs: src
27−license: BSD3
28−maintainer: jones3.hardy@gmail.com
29−name: rollbar-hs
30−synopsis: Core Rollbar data types and APIs.
31−tests:
32− doc-test:
33− dependencies:
34− - QuickCheck >= 2.9
35− - aeson >= 1.0
36− - base >= 4.9
37− - bytestring >= 0.10
38− - case-insensitive >= 1.2
39− - hspec >= 2.4
40− - hspec-golden-aeson >= 0.2
41− - rollbar-hs
42− - text >= 1.2
43− - unordered-containers >= 0.2
44− main: Main.hs
45− source-dirs: test
46−version: '0.3.1.0'
rollbar-hs.cabal+21−19
@@ -45,24 +45,25 @@ library
4545 Rollbar.Item.Person
4646 Rollbar.Item.Request
4747 Rollbar.Item.Server
48+ Rollbar.Aeson
4849 other-modules:
4950 Paths_rollbar_hs
5051 hs-source-dirs:
5152 src
5253 build-depends:
53− aeson >=1.0 && <1.5
54− , base >=4.9 && <5
55− , bytestring >=0.10 && <0.11
56− , case-insensitive >=1.2 && <1.3
57− , hostname >=1.0 && <1.1
58− , http-client >=0.5 && <0.6
59− , http-conduit >=2.2 && <2.4
60− , http-types >=0.9 && <0.13
61− , network >=2.6 && <2.9
62− , text >=1.2 && <1.3
63− , time >=1.6 && <1.9
64− , unordered-containers >=0.2 && <0.3
65− , uuid >=1.3 && <1.4
54+ aeson >=1.1
55+ , base >=4.9
56+ , bytestring >=0.10
57+ , case-insensitive >=1.2
58+ , hostname >=1.0
59+ , http-client >=0.5
60+ , http-conduit >=2.2
61+ , http-types >=0.8.6
62+ , network >=2.6.3
63+ , text >=1.2
64+ , time >=1.6
65+ , unordered-containers >=0.2
66+ , uuid >=1.3
6667 default-language: Haskell2010
6768
6869test-suite doc-test
@@ -79,13 +80,14 @@ test-suite doc-test
7980 test
8081 build-depends:
8182 QuickCheck >=2.9
82− , aeson >=1.0
83− , base >=4.9
84− , bytestring >=0.10
85− , case-insensitive >=1.2
83+ , aeson
84+ , base
85+ , bytestring
86+ , case-insensitive
87+ , hashable
8688 , hspec >=2.4
8789 , hspec-golden-aeson >=0.2
8890 , rollbar-hs
89− , text >=1.2
90− , unordered-containers >=0.2
91+ , text
92+ , unordered-containers
9193 default-language: Haskell2010
src/Rollbar/Aeson.hsnew file+22
@@ -0,0 +1,22 @@
1+{-# LANGUAGE CPP #-}
2+
3+module Rollbar.Aeson
4+ ( Key
5+ , textToKey
6+ ) where
7+
8+import Data.Text (Text)
9+#if MIN_VERSION_aeson(2,0,0)
10+import Data.Aeson.Key (Key)
11+import qualified Data.Aeson.Key as Key
12+#else
13+#endif
14+
15+#if MIN_VERSION_aeson(2,0,0)
16+textToKey :: Text -> Key
17+textToKey = Key.fromText
18+#else
19+type Key = Text
20+textToKey :: Text -> Key
21+textToKey = id
22+#endif
src/Rollbar/Item.hs+8
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE DataKinds #-}
23{-# LANGUAGE DeriveGeneric #-}
34{-# LANGUAGE NamedFieldPuns #-}
@@ -197,10 +198,17 @@ data Item a headers
197198 }
198199 deriving (Eq, Generic, Show)
199200
201+#if MIN_VERSION_aeson(2, 2, 0)
202+itemKVs
203+ :: (KeyValue e kv, RemoveHeaders headers, ToJSON v)
204+ => Item v headers
205+ -> [kv]
206+#else
200207itemKVs
201208 :: (KeyValue kv, RemoveHeaders headers, ToJSON v)
202209 => Item v headers
203210 -> [kv]
211+#endif
204212itemKVs Item{accessToken, itemData} =
205213 [ "access_token" .= accessToken
206214 , "data" .= itemData
src/Rollbar/Item/Body.hs+10−4
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE DeriveGeneric #-}
23{-# LANGUAGE GeneralizedNewtypeDeriving #-}
34{-# LANGUAGE NamedFieldPuns #-}
@@ -33,7 +34,7 @@ import Data.Aeson
3334 , (.=)
3435 )
3536import Data.Aeson.Encoding (pair)
36−import Data.Aeson.Types (typeMismatch)
37+import Data.Aeson.Types (explicitParseField, typeMismatch)
3738import Data.String (IsString)
3839
3940import GHC.Generics (Generic)
@@ -52,16 +53,21 @@ data Body arbitrary
5253 }
5354 deriving (Eq, Generic, Show)
5455
56+#if MIN_VERSION_aeson(2, 2, 0)
57+bodyKVs :: (KeyValue e kv, ToJSON v) => Body v -> [kv]
58+#else
5559bodyKVs :: (KeyValue kv, ToJSON v) => Body v -> [kv]
60+#endif
5661bodyKVs Message{messageBody, messageData} =
5762 [ "body" .= messageBody
5863 , "data" .= messageData
5964 ]
6065
6166instance FromJSON arbitrary => FromJSON (Body arbitrary) where
62− parseJSON (Object o') = do
63− o <- o' .: "message"
64− Message <$> o .: "body" <*> o .: "data"
67+ parseJSON (Object o') = explicitParseField parseMessage o' "message"
68+ where
69+ parseMessage (Object o) = Message <$> o .: "body" <*> o .: "data"
70+ parseMessage v = typeMismatch "Body arbitrary (message)" v
6571 parseJSON v = typeMismatch "Body arbitrary" v
6672
6773instance ToJSON arbitrary => ToJSON (Body arbitrary) where
src/Rollbar/Item/MissingHeaders.hs+8−3
@@ -3,6 +3,7 @@
33{-# LANGUAGE KindSignatures #-}
44{-# LANGUAGE ScopedTypeVariables #-}
55{-# LANGUAGE TypeOperators #-}
6+{-# LANGUAGE CPP #-}
67
78{-|
89 Module : Rollbar.Item.MissingHeaders
@@ -20,6 +21,7 @@ module Rollbar.Item.MissingHeaders
2021
2122import Data.Aeson
2223 (FromJSON, KeyValue, ToJSON, object, parseJSON, toJSON, (.=))
24+import Rollbar.Aeson
2325import Data.Bifunctor (bimap)
2426import Data.CaseInsensitive (mk, original)
2527import Data.Maybe (catMaybes)
@@ -31,7 +33,6 @@ import Network.HTTP.Types (Header, RequestHeaders)
3133
3234import qualified Data.ByteString as BS
3335import qualified Data.ByteString.Char8 as BSC8
34−import qualified Data.Text as T
3536import qualified Data.Text.Encoding as TE
3637
3738-- | The request headers with some missing
@@ -63,7 +64,11 @@ instance FromJSON (MissingHeaders headers) where
6364instance RemoveHeaders headers => ToJSON (MissingHeaders headers) where
6465 toJSON = object . catMaybes . requestHeadersKVs . removeHeaders
6566
67+#if MIN_VERSION_aeson(2, 2, 0)
68+requestHeadersKVs :: forall e kv. KeyValue e kv => RequestHeaders -> [Maybe kv]
69+#else
6670requestHeadersKVs :: forall kv. KeyValue kv => RequestHeaders -> [Maybe kv]
71+#endif
6772requestHeadersKVs = fmap go
6873 where
6974 go :: Header -> Maybe kv
@@ -72,5 +77,5 @@ requestHeadersKVs = fmap go
7277 val <- myDecodeUtf8 val'
7378 pure (key .= val)
7479
75−myDecodeUtf8 :: BS.ByteString -> Maybe T.Text
76−myDecodeUtf8 = either (const Nothing) Just . TE.decodeUtf8'
80+myDecodeUtf8 :: BS.ByteString -> Maybe Key
81+myDecodeUtf8 = either (const Nothing) (Just . textToKey) . TE.decodeUtf8'
src/Rollbar/Item/Request.hs+12−2
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE DeriveGeneric #-}
23{-# LANGUAGE GeneralizedNewtypeDeriving #-}
34{-# LANGUAGE NamedFieldPuns #-}
@@ -48,6 +49,7 @@ import GHC.Generics (Generic)
4849import Network.HTTP.Types (Query)
4950import Network.Socket (SockAddr(SockAddrInet), tupleToHostAddress)
5051
52+import Rollbar.Aeson
5153import Rollbar.Item.MissingHeaders
5254
5355import Text.Read (readMaybe)
@@ -96,14 +98,18 @@ instance ToJSON Get where
9698 toJSON (Get q) = object . catMaybes . queryKVs $ q
9799 toEncoding (Get q) = pairs . mconcat . catMaybes . queryKVs $ q
98100
99−queryKVs :: forall kv. (KeyValue kv) => Query -> [Maybe kv]
101+#if MIN_VERSION_aeson(2, 2, 0)
102+queryKVs :: forall e kv. KeyValue e kv => Query -> [Maybe kv]
103+#else
104+queryKVs :: forall kv. KeyValue kv => Query -> [Maybe kv]
105+#endif
100106queryKVs = fmap go
101107 where
102108 go :: (BS.ByteString, Maybe BS.ByteString) -> Maybe kv
103109 go (key', val') = do
104110 key <- myDecodeUtf8 key'
105111 let val = val' >>= myDecodeUtf8
106− pure (key .= val)
112+ pure (textToKey key .= val)
107113
108114-- | The HTTP Verb
109115newtype Method
@@ -149,7 +155,11 @@ instance ToJSON IP where
149155 toJSON (IP ip) = toJSON (show ip)
150156 toEncoding (IP ip) = toEncoding (show ip)
151157
158+#if MIN_VERSION_aeson(2, 2, 0)
159+requestKVs :: (KeyValue e kv, RemoveHeaders headers) => Request headers -> [kv]
160+#else
152161requestKVs :: (KeyValue kv, RemoveHeaders headers) => Request headers -> [kv]
162+#endif
153163requestKVs Request{get, headers, method, queryString, rawBody, url, userIP} =
154164 [ "body" .= rawBody
155165 , "GET" .= get
src/Rollbar/Item/Server.hs+5
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE DeriveGeneric #-}
23{-# LANGUAGE GeneralizedNewtypeDeriving #-}
34{-# LANGUAGE NamedFieldPuns #-}
@@ -57,7 +58,11 @@ data Server
5758 }
5859 deriving (Eq, Generic, Show)
5960
61+#if MIN_VERSION_aeson(2, 2, 0)
62+serverKVs :: KeyValue e kv => Server -> [Maybe kv]
63+#else
6064serverKVs :: KeyValue kv => Server -> [Maybe kv]
65+#endif
6166serverKVs Server{branch, host, root, serverCodeVersion} =
6267 [ ("host" .=) <$> host
6368 , ("root" .=) <$> root
stack.yamlnew file+6
@@ -0,0 +1,6 @@
1+resolver: lts-23.7
2+packages:
3+- .
4+
5+nix:
6+ packages: [ zlib ]
test/Rollbar/Item/Data/Test.hs+1−1
@@ -39,6 +39,6 @@ requiredBodyKeys = ["trace", "trace_chain", "message", "crash_report"]
3939key :: Text -> Value -> [(Text, Value)]
4040key k = \case
4141 Object o -> case Data.HashMap.Strict.lookupDefault Null k o of
42− Object o -> Data.HashMap.Strict.toList o
42+ Object o' -> Data.HashMap.Strict.toList o'
4343 _ -> mempty
4444 _ -> mempty
test/Rollbar/Item/MissingHeaders/Test.hs+2
@@ -9,6 +9,7 @@ module Rollbar.Item.MissingHeaders.Test where
99import Data.Aeson (Value (Object), decode', encode,
1010 toJSON)
1111import Data.Functor (void)
12+import Data.Hashable
1213import Data.HashSet (HashSet)
1314import Data.Text (Text)
1415
@@ -91,4 +92,5 @@ keys = \case
9192 Object o -> Data.HashSet.fromMap (void o)
9293 _ -> mempty
9394
95+notMember :: (Eq a, Hashable a) => a -> HashSet a -> Bool
9496notMember x = not . Data.HashSet.member x