-- | Internal functions for timestats
module Debug.TimeStats.Internal
  ( formatIntWithSeparator
  ) where


-- | Formats an int with a thousand separator.
--
-- For instance
--
-- > formatIntWithSeparator '_' 123456789 "a" == "123_456_789a"
--
formatIntWithSeparator :: Char -> Int -> ShowS
formatIntWithSeparator :: Char -> Int -> ShowS
formatIntWithSeparator Char
sep Int
x0 String
s0 =
    if Int
x0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then Int -> ShowS
forall {a}. (Show a, Integral a) => a -> ShowS
go Int
x0 String
s0 else Char
'-' Char -> ShowS
forall a. a -> [a] -> [a]
: Int -> ShowS
forall {a}. (Show a, Integral a) => a -> ShowS
go (-Int
x0) String
s0
  where
    -- precondition: x >= 0
    go :: a -> ShowS
go a
x String
s =
      let (a
d, a
m) = a -> a -> (a, a)
forall a. Integral a => a -> a -> (a, a)
divMod a
x a
1000
       in if a
d a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0 then a -> ShowS
forall a. Show a => a -> ShowS
shows a
m String
s
          else a -> ShowS
go a
d ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Char
sep Char -> ShowS
forall a. a -> [a] -> [a]
: a -> String
forall {a}. (Ord a, Num a) => a -> String
pad999 a
m String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> ShowS
forall a. Show a => a -> ShowS
shows a
m String
s

    -- precondition: 0 <= m && m <= 999
    pad999 :: a -> String
pad999 a
m
      | a
m a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
10    = String
"00"
      | a
m a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
100   =  String
"0"
      | Bool
otherwise =   String
""