module Web.Stripe.Utils ( Amount(..) , Count(..) , Currency(..) , Description(..) , Offset(..) , optionalArgs , jGet , mjGet {- Re-Export -} , UTCTime(..) , fromSeconds , toSeconds ) where import Data.Time.Clock ( UTCTime(..) ) import Data.Time.Clock.POSIX ( posixSecondsToUTCTime, utcTimeToPOSIXSeconds ) import Data.Time.Format ( ) -- imports Show instance for UTCTime import Text.JSON ( Result(..), JSObject, JSON(..), JSValue(..) , resultToEither, valFromObj ) ----------------------- -- Common Data Types -- ----------------------- -- | Represents an amount in cents in the Stripe system. newtype Amount = Amount { unAmount :: Int } deriving Show -- | A maximum number of objects that the Stripe API will return. This value -- should be between 1 and 100, inclusive. newtype Count = Count { unCount :: Int } deriving Show -- | Represents a currency (e.g., "usd") in the Stripe system. This is -- a 3-letter ISO code. newtype Currency = Currency { unCurrency :: String } deriving Show -- | Describes an object in the Stripe system. newtype Description = Description { unDescription :: String } deriving Show -- | A positive integer that is an offset into the array of objects returned -- by the Stripe API. newtype Offset = Offset { unOffset :: Int } deriving Show ----------------------- -- Utility Functions -- ----------------------- -- | Convert a time in seconds (from Stripe's servers) to 'UTCTime'. See -- "Data.Time.Format" for more on working with 'UTCTime'. fromSeconds :: Integer -> UTCTime fromSeconds = posixSecondsToUTCTime . fromInteger -- | Convert a 'UTCTime' back to an Integer suitable for use with Stripe's API. toSeconds :: UTCTime -> Integer toSeconds = round . utcTimeToPOSIXSeconds -- | Takes a list of key-value arguments, where the value is optional, and -- returns a list of key-value pairs with only the supplied values. -- -- Essentially, this filters out all 'Nothing's and unwraps the 'Just's. -- -- >>> optionalArgs [("k1", Just "supplied"), ("k2", Nothing)] -- [("k1","supplied")] optionalArgs :: [(String, Maybe String)] -> [(String, String)] optionalArgs [] = [] optionalArgs ((_, Nothing):xs) = optionalArgs xs optionalArgs ((a, Just b):xs) = (a, b):optionalArgs xs -- | Convenience function to get a field from a given 'JSON' object. jGet :: JSON a => JSObject JSValue -> String -> Result a jGet = flip valFromObj -- | Attempts to retrieve a field from a given 'JSON' object, failing -- gracefully with 'Nothing' if such a field is not found. mjGet :: JSON a => JSObject JSValue -> String -> Result (Maybe a) mjGet obj = return . either (\_ -> Nothing) Just . resultToEither . jGet obj