1 {-# LANGUAGE ViewPatterns #-}
2 module Cryptsy
.API
.Public
3 ( CryptsyError
(..), PubCryptsy
9 import Network
.Browser
(BrowserAction
, defaultGETRequest_
, request
)
10 import Network
.HTTP
.Base
(Response
(..))
11 import Network
.TCP
(HandleStream
)
14 import Data
.Aeson
(Value
(Object
), json
)
17 import Data
.Attoparsec
.ByteString
.Lazy
(eitherResult
, parse
)
20 import qualified Data
.ByteString
.Lazy
as L
(ByteString
)
23 import Control
.Monad
.Trans
.Either (EitherT
, left
, right
)
26 import Network
.URI
(parseAbsoluteURI
)
29 import Data
.Text
(Text
, pack
)
32 import Control
.Monad
.Trans
(lift
)
34 -- unordered-containers
35 import qualified Data
.HashMap
.Strict
as HM
(lookup)
37 data CryptsyError
= BadUrl
{ url
:: String }
38 | BadResponse
{ response
:: Response L
.ByteString
}
39 | FailParseResponse
{ body
:: L
.ByteString
, message
:: String }
40 | ErrorResponse
{ error :: Value
}
41 | UnsuccessfulResponse
{ jsonResponse
:: Value
}
42 | FailParseReturn
{ value :: Value
, message
:: String }
45 type PubCryptsy
= EitherT CryptsyError
(BrowserAction
(HandleStream L
.ByteString
))
48 dataKey
= pack
"return"
51 errMsgKey
= pack
"error"
53 pubCryptsy
:: String -> PubCryptsy Value
54 pubCryptsy apiurl
= do
55 uri
<- maybe (left
$ BadUrl apiurl
) right
$ parseAbsoluteURI apiurl
56 let req
= defaultGETRequest_ uri
57 (_
, resp
) <- lift
$ request req
58 bodyBytes
<- case rspCode resp
of
59 (2, 0, 0) -> right
$ rspBody resp
60 _
-> left
$ BadResponse resp
61 valueJSON
<- either (left
. FailParseResponse bodyBytes
) right
62 . eitherResult
$ parse json bodyBytes
64 Object
(HM
.lookup dataKey
-> Just dat
) -> right dat
65 Object
(HM
.lookup errMsgKey
-> Just errMsg
) ->
66 left
$ ErrorResponse errMsg
67 _
-> left
$ UnsuccessfulResponse valueJSON