packages feed

fb-util-0.1.0.1: Util/PrettyPrint.hs

{-
  Copyright (c) Meta Platforms, Inc. and affiliates.
  All rights reserved.

  This source code is licensed under the BSD-style license found in the
  LICENSE file in the root directory of this source tree.
-}

module Util.PrettyPrint
  ( renderNumWithUnit
  , renderPercent
  , renderIncrease
  , renderNum
  , renderInt
  , renderBytes
  , renderBytesString
  ) where

import Data.Text (Text)
import qualified Data.Text as Text
import Text.Printf
import TextShow

renderNumWithUnit :: Text -> Double -> Text
renderNumWithUnit unit num = renderNum num <> " " <> unit

-- | Render a fraction as a percentage
renderPercent :: Double -> Double -> Text
renderPercent x y
  | y == 0     = "Infinite"
  | otherwise  = Text.pack $ printf (printf "%%.%df%%%%" precision) frac
  where
    frac = x / y * 100
    -- Make sure we always have enough signifigant digits
    precision = max 0 $ ceiling (negate $ logBase 10 frac) + 2 :: Int

-- | Render an increase as either a percent or times
renderIncrease :: Double -> Double -> Text
renderIncrease x y
  | y == 0    = "Infinite"
  | frac < 2  = renderPercent (x - y) y
  | frac < 10 = Text.pack $ printf "%.2fx" frac
  | otherwise = showt (round frac :: Int) <> "x"
  where
    frac = x / y

renderNum :: Double -> Text
renderNum num
  | num < 10 = Text.pack $ printf "%.2f" num
  | otherwise = renderInt $ round num

renderInt :: Int -> Text
renderInt num
  | num < 1000 = showt num
  | num < 1000000 = showt (num `div` 1000) <> "k"
  | otherwise = showt (num `div` 1000000) <> "M"

renderBytes :: Int -> Text
renderBytes b = Text.pack $ renderBytesString b

renderBytesString :: Int -> String
renderBytesString b
 | b' > gb = printf "%.2f GiB" (b' / gb)
 | b' > mb = printf "%.2f MiB" (b' / mb)
 | b' > kb = printf "%.2f kiB" (b' / kb)
 | otherwise = printf "%d bytes" (fromIntegral b :: Integer)
 where
  kb, mb, gb :: Double
  kb = 1024
  mb = 1024*kb
  gb = 1024*mb
  b' = fromIntegral b :: Double