{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}

-- | Formatters for high-res, real-time and timer clock values from "System.Clock".

module Formatting.Clock (timeSpecs) where

import Data.Text.Lazy.Builder
import Formatting
import Formatting.Internal
import System.Clock

fmt :: Integer -> Builder
fmt :: Integer -> Builder
fmt Integer
diff
  | Just Double
i <- Integer -> Maybe Double
scale ((Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
9) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
60 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
60 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
24) = Format Builder (Double -> Builder) -> Double -> Builder
forall a. Format Builder a -> a
bprint (Int -> Format Builder (Double -> Builder)
forall a r. Real a => Int -> Format r (a -> r)
fixed Int
2 Format Builder (Double -> Builder)
-> Format Builder Builder -> Format Builder (Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Builder Builder
" d") Double
i
  | Just Double
i <- Integer -> Maybe Double
scale ((Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
9) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
60 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
60) = Format Builder (Double -> Builder) -> Double -> Builder
forall a. Format Builder a -> a
bprint (Int -> Format Builder (Double -> Builder)
forall a r. Real a => Int -> Format r (a -> r)
fixed Int
2 Format Builder (Double -> Builder)
-> Format Builder Builder -> Format Builder (Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Builder Builder
" h") Double
i
  | Just Double
i <- Integer -> Maybe Double
scale ((Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
9) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
60) = Format Builder (Double -> Builder) -> Double -> Builder
forall a. Format Builder a -> a
bprint (Int -> Format Builder (Double -> Builder)
forall a r. Real a => Int -> Format r (a -> r)
fixed Int
2 Format Builder (Double -> Builder)
-> Format Builder Builder -> Format Builder (Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Builder Builder
" m") Double
i
  | Just Double
i <- Integer -> Maybe Double
scale (Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
9) = Format Builder (Double -> Builder) -> Double -> Builder
forall a. Format Builder a -> a
bprint (Int -> Format Builder (Double -> Builder)
forall a r. Real a => Int -> Format r (a -> r)
fixed Int
2 Format Builder (Double -> Builder)
-> Format Builder Builder -> Format Builder (Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Builder Builder
" s") Double
i
  | Just Double
i <- Integer -> Maybe Double
scale (Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
6) = Format Builder (Double -> Builder) -> Double -> Builder
forall a. Format Builder a -> a
bprint (Int -> Format Builder (Double -> Builder)
forall a r. Real a => Int -> Format r (a -> r)
fixed Int
2 Format Builder (Double -> Builder)
-> Format Builder Builder -> Format Builder (Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Builder Builder
" ms") Double
i
  | Just Double
i <- Integer -> Maybe Double
scale (Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
3) = Format Builder (Double -> Builder) -> Double -> Builder
forall a. Format Builder a -> a
bprint (Int -> Format Builder (Double -> Builder)
forall a r. Real a => Int -> Format r (a -> r)
fixed Int
2 Format Builder (Double -> Builder)
-> Format Builder Builder -> Format Builder (Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Builder Builder
" us") Double
i
  | Bool
otherwise = Format Builder (Integer -> Builder) -> Integer -> Builder
forall a. Format Builder a -> a
bprint (Format Builder (Integer -> Builder)
forall a r. Integral a => Format r (a -> r)
int Format Builder (Integer -> Builder)
-> Format Builder Builder -> Format Builder (Integer -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Builder Builder
" ns") Integer
diff
  where
    scale :: Integer -> Maybe Double
    scale :: Integer -> Maybe Double
scale Integer
i =
      if Integer
diff Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
i
        then Double -> Maybe Double
forall a. a -> Maybe a
Just (Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
diff Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
i)
        else Maybe Double
forall a. Maybe a
Nothing

-- | Same as @durationNS@ but works on `TimeSpec` from the clock package.
timeSpecs :: Format r (TimeSpec -> TimeSpec -> r)
timeSpecs :: forall r. Format r (TimeSpec -> TimeSpec -> r)
timeSpecs = ((Builder -> r) -> TimeSpec -> TimeSpec -> r)
-> Format r (TimeSpec -> TimeSpec -> r)
forall r a. ((Builder -> r) -> a) -> Format r a
Format (\Builder -> r
g TimeSpec
x TimeSpec
y -> Builder -> r
g (TimeSpec -> TimeSpec -> Builder
fmt0 TimeSpec
x TimeSpec
y))
  where
    fmt0 :: TimeSpec -> TimeSpec -> Builder
fmt0 (TimeSpec Int64
s1 Int64
n1) (TimeSpec Int64
s2 Int64
n2) = Integer -> Builder
fmt Integer
diff
      where
        diff :: Integer
        diff :: Integer
diff = Integer
a2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
a1
        a1 :: Integer
a1 = (Int64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
s1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
9) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
n1
        a2 :: Integer
a2 = (Int64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
s2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
9) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
n2