-- | Internal newtype for deserializing timestamps
module Calamity.Internal.UnixTimestamp (
    UnixTimestamp (..),
    unixToMilliseconds,
    millisecondsToUnix,
) where

import Calamity.Internal.Utils ()
import Control.Arrow
import Data.Aeson
import Data.Aeson.Encoding (word64)
import Data.Time
import Data.Time.Clock.POSIX
import Data.Word
import TextShow

newtype UnixTimestamp = UnixTimestamp
    { UnixTimestamp -> UTCTime
unUnixTimestamp :: UTCTime
    }
    deriving (Int -> UnixTimestamp -> ShowS
[UnixTimestamp] -> ShowS
UnixTimestamp -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UnixTimestamp] -> ShowS
$cshowList :: [UnixTimestamp] -> ShowS
show :: UnixTimestamp -> String
$cshow :: UnixTimestamp -> String
showsPrec :: Int -> UnixTimestamp -> ShowS
$cshowsPrec :: Int -> UnixTimestamp -> ShowS
Show) via UTCTime
    deriving (Int -> UnixTimestamp -> Builder
Int -> UnixTimestamp -> Text
Int -> UnixTimestamp -> Text
[UnixTimestamp] -> Builder
[UnixTimestamp] -> Text
[UnixTimestamp] -> Text
UnixTimestamp -> Builder
UnixTimestamp -> Text
UnixTimestamp -> Text
forall a.
(Int -> a -> Builder)
-> (a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> TextShow a
showtlList :: [UnixTimestamp] -> Text
$cshowtlList :: [UnixTimestamp] -> Text
showtl :: UnixTimestamp -> Text
$cshowtl :: UnixTimestamp -> Text
showtlPrec :: Int -> UnixTimestamp -> Text
$cshowtlPrec :: Int -> UnixTimestamp -> Text
showtList :: [UnixTimestamp] -> Text
$cshowtList :: [UnixTimestamp] -> Text
showt :: UnixTimestamp -> Text
$cshowt :: UnixTimestamp -> Text
showtPrec :: Int -> UnixTimestamp -> Text
$cshowtPrec :: Int -> UnixTimestamp -> Text
showbList :: [UnixTimestamp] -> Builder
$cshowbList :: [UnixTimestamp] -> Builder
showb :: UnixTimestamp -> Builder
$cshowb :: UnixTimestamp -> Builder
showbPrec :: Int -> UnixTimestamp -> Builder
$cshowbPrec :: Int -> UnixTimestamp -> Builder
TextShow) via FromStringShow UTCTime

unixToMilliseconds :: UnixTimestamp -> Word64
unixToMilliseconds :: UnixTimestamp -> Word64
unixToMilliseconds =
    UnixTimestamp -> UTCTime
unUnixTimestamp
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> UTCTime -> POSIXTime
utcTimeToPOSIXSeconds
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a. Real a => a -> Rational
toRational
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall a. Num a => a -> a -> a
* Rational
1000)
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a b. (RealFrac a, Integral b) => a -> b
round

millisecondsToUnix :: Word64 -> UnixTimestamp
millisecondsToUnix :: Word64 -> UnixTimestamp
millisecondsToUnix =
    forall a. Real a => a -> Rational
toRational
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a. Fractional a => Rational -> a
fromRational
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall a. Fractional a => a -> a -> a
/ POSIXTime
1000)
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> POSIXTime -> UTCTime
posixSecondsToUTCTime
        forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> UTCTime -> UnixTimestamp
UnixTimestamp

instance ToJSON UnixTimestamp where
    toJSON :: UnixTimestamp -> Value
toJSON =
        UnixTimestamp -> UTCTime
unUnixTimestamp
            forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> UTCTime -> POSIXTime
utcTimeToPOSIXSeconds
            forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a. Real a => a -> Rational
toRational
            forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a b. (RealFrac a, Integral b) => a -> b
round
            forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a. ToJSON a => a -> Value
toJSON @Word64
    toEncoding :: UnixTimestamp -> Encoding
toEncoding =
        UnixTimestamp -> UTCTime
unUnixTimestamp
            forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> UTCTime -> POSIXTime
utcTimeToPOSIXSeconds
            forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a. Real a => a -> Rational
toRational
            forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a b. (RealFrac a, Integral b) => a -> b
round
            forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Word64 -> Encoding
word64

instance FromJSON UnixTimestamp where
    parseJSON :: Value -> Parser UnixTimestamp
parseJSON =
        forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
withScientific String
"UnixTimestamp" forall a b. (a -> b) -> a -> b
$
            forall a. Real a => a -> Rational
toRational
                forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall a. Fractional a => Rational -> a
fromRational
                forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> POSIXTime -> UTCTime
posixSecondsToUTCTime
                forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> UTCTime -> UnixTimestamp
UnixTimestamp
                forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (f :: * -> *) a. Applicative f => a -> f a
pure