Massive refactoring into smaller modules.
[haskell-cryptsy-api.git] / Cryptsy / API / Public / MarketData / New.hs
blob2f4fd4d51c831c64417a3dd9accbaf582df74f2c
1 {-# LANGUAGE ViewPatterns #-}
2 module Cryptsy.API.Public.MarketData.New
3 ( GMarketData(..), MarketData
4 , withComponents, withMarket
5 , getMarketData, marketData
7 where
9 -- aeson
10 import Data.Aeson ( FromJSON(..), Value(Object), Object, withObject )
11 import Data.Aeson.Types (Parser, Result(..), parse)
13 -- base
14 import Data.Function ( ($) )
15 import Data.Functor ( fmap, (<$>) )
16 import Data.Maybe (Maybe(..))
17 import Data.Traversable (mapM)
18 import Prelude ( Show, String )
20 -- either
21 import Control.Monad.Trans.Either (left, right)
23 -- text
24 import Data.Text (Text, pack)
26 -- unordered-containers
27 import Data.HashMap.Strict (HashMap)
28 import qualified Data.HashMap.Strict as HM (lookup)
30 -- this pacakge
31 import Cryptsy.API.Public
32 import Cryptsy.API.Public.SingleMarket ( GSingleMarket )
34 marketdatav2URL :: String
35 marketdatav2URL = "http://pubapi.cryptsy.com/api.php?method=marketdatav2"
37 newtype GMarketData p q dt t =
38 MarketData { markets :: (HashMap Text (GSingleMarket p q dt t)) }
39 deriving Show
40 type MarketData = GMarketData Text Text Text Text
42 instance (FromJSON p, FromJSON q, FromJSON dt, FromJSON t) =>
43 FromJSON (GMarketData p q dt t)
44 where
45 parseJSON = withObject "markets" $ withComponents parseJSON
47 -- |Build parser for multiple markets from parser for single market.
48 withComponents :: (Value -> Parser (GSingleMarket p q dt t)) -- ^ market parser
49 -> Object -> Parser (GMarketData p q dt t)
50 withComponents parseMarket = fmap MarketData <$> mapM parseMarket
52 -- |Build parser for multiple markets from parser for single market object.
53 withMarket :: (Object -> Parser (GSingleMarket p q dt t)) -- ^ market parser
54 -> Object -> Parser (GMarketData p q dt t)
55 withMarket parseMarket = withComponents (withObject "market" parseMarket)
57 {-|
58 "Raw" request, does not convert the JSON value, but simply returns the JSON
59 value bound to the "return" key from the response body.
61 getMarketData :: PubCryptsy Value
62 getMarketData = pubCryptsy marketdatav2URL
64 marketsKey :: Text
65 marketsKey = pack "markets"
67 {-|
68 "Cooked" request, extracts the JSON object bound to the "market" key of the
69 object boudn to the "return" key and converts it.
71 marketData :: (Object -> Parser (GMarketData p q dt t)) -- ^ market data parser
72 -> PubCryptsy (GMarketData p q dt t)
73 marketData parseMarkets = do
74 ret <- getMarketData
75 mkts <- case ret of
76 Object (HM.lookup marketsKey -> Just m) -> right m
77 _ -> left $ FailParseReturn ret "Missing 'markets' key."
78 case parse (withObject "markets" parseMarkets) mkts of
79 Error err -> left $ FailParseReturn ret err
80 Success v -> right v