stripe-0.1: src/Web/Stripe/Utils.hs
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