{-# LANGUAGE OverloadedStrings #-} module Network.Shopify.Types ( ShopifyID , JsonExtending(..), ShopifyMeta(..), ShopifyDate(..), dateToQuery , ProductID, LineItemID, CollectionID, OrderID , Sku ) where import Data.Int import Control.Applicative import qualified Data.Text as T import Data.Aeson ((.:), (.=)) import qualified Data.Aeson as JS import qualified Data.Aeson.Types as JS import qualified Data.ByteString as BS import Data.Time import Network.HTTP.Types.QueryLike (toQueryValue) type ShopifyID = Int64 type ProductID = ShopifyID type LineItemID = ShopifyID type CollectionID = ShopifyID type OrderID = ShopifyID type Sku = T.Text class JsonExtending a where jsonExtender :: a -> [JS.Pair] dateToQuery :: UTCTime -> Maybe BS.ByteString dateToQuery = toQueryValue . formatTime defaultTimeLocale (iso8601DateFormat $ Just "") data ShopifyDate = ShopifyDate {actualTime::UTCTime} instance JS.FromJSON ShopifyDate where parseJSON (JS.String t) = case parseTimeM True defaultTimeLocale "%FT%T%Z" (T.unpack t) of Just d -> pure $ ShopifyDate d Nothing -> fail "could not parse ISO-8601 date" parseJSON v = fail ("ShopifyDate not a string: "++show v) instance JS.ToJSON ShopifyDate where toJSON (ShopifyDate t) = JS.String (T.pack $ formatTime defaultTimeLocale "%FT%T%z" t) data ShopifyMeta = ShopifyMeta { metaId :: ShopifyID , metaCreated :: UTCTime , metaUpdated :: UTCTime } deriving (Show) instance JsonExtending ShopifyMeta where jsonExtender m = ["id" .= metaId m ,"created_at" .= (ShopifyDate $ metaCreated m) ,"updated_at" .= (ShopifyDate $ metaUpdated m) ] instance JS.FromJSON ShopifyMeta where parseJSON (JS.Object v) = ShopifyMeta <$> v .: "id" <*> (v .: "created_at" >>= return . actualTime) <*> (v .: "updated_at" >>= return . actualTime) parseJSON _ = fail "ShopifyMeta not an object"