content: {-# 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 diff
    | Just i <- scale ((10 ^ 9) * 60 * 60 * 24) = bprint (fixed 2 % " d") i
    | Just i <- scale ((10 ^ 9) * 60 * 60) = bprint (fixed 2 % " h") i
    | Just i <- scale ((10 ^ 9) * 60) = bprint (fixed 2 % " m") i
    | Just i <- scale (10 ^ 9) = bprint (fixed 2 % " s") i
    | Just i <- scale (10 ^ 6) = bprint (fixed 2 % " ms") i
    | Just i <- scale (10 ^ 3) = bprint (fixed 2 % " us") i
    | otherwise = bprint (int % " ns") diff
    where
      scale :: Integer -> Maybe Double
      scale i =
        if diff >= i
          then Just (fromIntegral diff / fromIntegral i)
          else Nothing
  
  -- | Same as @durationNS@ but works on `TimeSpec` from the clock package.
  timeSpecs :: Format r (TimeSpec -> TimeSpec -> r)
  timeSpecs = Format (\g x y -> g (fmt0 x y))
    where
      fmt0 (TimeSpec s1 n1) (TimeSpec s2 n2) = fmt diff
        where
          diff :: Integer
          diff = a2 - a1
          a1 = (fromIntegral s1 * 10 ^ 9) + fromIntegral n1
          a2 = (fromIntegral s2 * 10 ^ 9) + fromIntegral n2
  