{-# LANGUAGE OverloadedStrings #-}

module Skeletest.Internal.Utils.Timer (
  withTimer,
  renderDuration,
) where

import Data.Text (Text)
import Data.Text qualified as Text
import Data.Time (NominalDiffTime, diffUTCTime, getCurrentTime)
import Numeric (showFFloat)

withTimer :: IO a -> IO (a, NominalDiffTime)
withTimer :: forall a. IO a -> IO (a, NominalDiffTime)
withTimer IO a
m = do
  UTCTime
start <- IO UTCTime
getCurrentTime
  a
a <- IO a
m
  UTCTime
end <- IO UTCTime
getCurrentTime
  (a, NominalDiffTime) -> IO (a, NominalDiffTime)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
a, UTCTime
end UTCTime -> UTCTime -> NominalDiffTime
`diffUTCTime` UTCTime
start)

renderDuration :: NominalDiffTime -> Text
renderDuration :: NominalDiffTime -> Text
renderDuration NominalDiffTime
duration = (String -> Text
Text.pack (String -> Text)
-> (NominalDiffTime -> String) -> NominalDiffTime -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NominalDiffTime -> String
forall {a}. Real a => a -> String
showRounded) NominalDiffTime
duration Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"s"
 where
  showRounded :: a -> String
showRounded a
n = Maybe Int -> Double -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2) (a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
n :: Double) String
""