1 {-# LANGUAGE FlexibleContexts, ViewPatterns #-}
2 module Cryptsy
.API
.Public
.MarketData
3 ( GMarketData
(..), MarketData
4 , withComponents
, withMarket
5 , onMarkets
, singleMarketData
6 , module Cryptsy
.API
.Public
7 , module Cryptsy
.API
.Public
.Market
8 -- |Re-exported from Data.Aeson
10 -- |Re-exported from Data.HashMap.Strict
16 import Data
.Aeson
( FromJSON
(..), Object
, withObject
)
19 import Control
.Monad
(fail)
20 import Data
.Function
(($), (.))
21 import Data
.Functor
(fmap, (<$>))
22 import Data
.List
((++))
23 import Data
.Maybe (maybe)
24 import Data
.String (String)
25 import Data
.Traversable
(mapM)
26 import Prelude
(Show(show))
29 import Data
.Text
(pack
, unpack
)
31 -- unordered-containers
32 import Data
.HashMap
.Strict
(HashMap
, toList
)
33 import qualified Data
.HashMap
.Strict
as HM
(lookup)
36 import Cryptsy
.API
.Public
37 import Cryptsy
.API
.Public
.Market
45 -- |general market data parameterized by types for prices, quantities,
46 -- date/time values, and totals (price * quantity)
47 newtype GMarketData p q dt t
=
48 MarketData
{ markets
:: HashMap Text
(GMarket p q dt t
) }
50 type MarketData
= GMarketData CryptsyNum CryptsyNum Text CryptsyNum
52 instance (FromJSON p
, FromJSON q
, FromJSON dt
, FromJSON t
) =>
53 FromJSON
(GMarketData p q dt t
)
55 parseJSON
= withObject
"markets" $ withComponents parseJSON
57 -- |unpacked 'marketsKey'
59 marketsStr
= "markets"
61 -- |failure message when 'marketsKey' is missing
63 missingMsg
= "Missing '" ++ marketsStr
++ "' key."
65 -- |key in JSON object for market data
67 marketsKey
= pack marketsStr
69 -- |Apply a parser on the 'marketsKey' of an object. If not an object or the
70 -- key is missing, fail.
71 onMarkets
:: (Value
-> Parser a
) -> Value
-> Parser a
72 onMarkets parser
= withObject marketsStr
$
73 maybe (fail missingMsg
) parser
. HM
.lookup marketsKey
75 -- |Build parser for multiple markets from parser for single market.
76 withComponents
:: (Value
-> Parser
(GMarket p q dt t
)) -- ^ market parser
77 -> Object
-> Parser
(GMarketData p q dt t
)
78 withComponents parseMarket
= fmap MarketData
<$> mapM parseMarket
80 -- |Build parser for multiple markets from parser for single market object.
81 withMarket
:: (Object
-> Parser
(GMarket p q dt t
)) -- ^ market parser
82 -> Object
-> Parser
(GMarketData p q dt t
)
83 withMarket parseMarket
= withComponents
(withObject
"market" parseMarket
)
85 singleMarketData
:: FromJSON
(GMarket p q dt t
)
87 -> PubCryptsy
(GMarket p q dt t
)
88 singleMarketData
(unpack
-> reqMarket
) = pubCryptsy marketURL parseSingleMarket
90 marketURL
= pubURL
$ "singlemarketdata&marketid=" ++ reqMarket
91 parseSingleMarket
= withObject
"Market" $ \o
->
93 [] -> fail "No market returned."
94 [(_
, v
)] -> parseJSON v
95 _
-> fail "Multiple markets returned."