    module TextBuilderDev.Domains.Other where

    import TextBuilder
    import TextBuilderDev.Domains.Digits
    import TextBuilderDev.Prelude hiding (intercalate)

    -- | Data size in decimal notation over amount of bytes.
    --
    -- >>> approximateDataSize 999
    -- "999B"
    --
    -- >>> approximateDataSize 9999
    -- "9.9kB"
    --
    -- >>> approximateDataSize (-9999)
    -- "-9.9kB"
    --
    -- >>> approximateDataSize 1234567890
    -- "1.2GB"
    --
    -- >>> approximateDataSize 10000000000000000000000000000000023
    -- "10,000,000,000YB"
    {-# INLINEABLE approximateDataSize #-}
    approximateDataSize :: (Integral a) => a -> TextBuilder
    approximateDataSize :: forall a. Integral a => a -> TextBuilder
    approximateDataSize = (a -> TextBuilder) -> a -> TextBuilder
    forall a. (Ord a, Num a) => (a -> TextBuilder) -> a -> TextBuilder
    signed \a
    a ->
      if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1000
        then a -> TextBuilder
    forall a. Integral a => a -> TextBuilder
    decimal a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "B"
        else
          if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1000000
            then a -> a -> TextBuilder
    forall {a}. Integral a => a -> a -> TextBuilder
    dividedDecimal a
    100 a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "kB"
            else
              if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1000000000
                then a -> a -> TextBuilder
    forall {a}. Integral a => a -> a -> TextBuilder
    dividedDecimal a
    100000 a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "MB"
                else
                  if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1000000000000
                    then a -> a -> TextBuilder
    forall {a}. Integral a => a -> a -> TextBuilder
    dividedDecimal a
    100000000 a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "GB"
                    else
                      if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1000000000000000
                        then a -> a -> TextBuilder
    forall {a}. Integral a => a -> a -> TextBuilder
    dividedDecimal a
    100000000000 a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "TB"
                        else
                          if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1000000000000000000
                            then a -> a -> TextBuilder
    forall {a}. Integral a => a -> a -> TextBuilder
    dividedDecimal a
    100000000000000 a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "PB"
                            else
                              if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1000000000000000000000
                                then a -> a -> TextBuilder
    forall {a}. Integral a => a -> a -> TextBuilder
    dividedDecimal a
    100000000000000000 a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "EB"
                                else
                                  if a
    a a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1000000000000000000000000
                                    then a -> a -> TextBuilder
    forall {a}. Integral a => a -> a -> TextBuilder
    dividedDecimal a
    100000000000000000000 a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "ZB"
                                    else a -> a -> TextBuilder
    forall {a}. Integral a => a -> a -> TextBuilder
    dividedDecimal a
    100000000000000000000000 a
    a TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "YB"
      where
        dividedDecimal :: a -> a -> TextBuilder
    dividedDecimal a
    divisor a
    n =
          let byDivisor :: a
    byDivisor = a -> a -> a
    forall a. Integral a => a -> a -> a
    div a
    n a
    divisor
              byExtraTen :: a
    byExtraTen = a -> a -> a
    forall a. Integral a => a -> a -> a
    div a
    byDivisor a
    10
              remainder :: a
    remainder = a
    byDivisor a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    byExtraTen a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    10
              separatorChar :: Char
    separatorChar = Char
    ','
           in if a
    remainder a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    0 Bool -> Bool -> Bool
    || a
    byExtraTen a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    >= a
    10
                then Char -> a -> TextBuilder
    forall a. Integral a => Char -> a -> TextBuilder
    thousandSeparatedDecimal Char
    separatorChar a
    byExtraTen
                else Char -> a -> TextBuilder
    forall a. Integral a => Char -> a -> TextBuilder
    thousandSeparatedDecimal Char
    separatorChar a
    byExtraTen TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "." TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> a -> TextBuilder
    forall a. Integral a => a -> TextBuilder
    decimalDigit a
    remainder

    -- | Double with a fixed number of decimal places.
    --
    -- >>> doubleFixedPoint 4 0.123456
    -- "0.1235"
    --
    -- >>> doubleFixedPoint 2 2.1
    -- "2.10"
    --
    -- >>> doubleFixedPoint (-2) 2.1
    -- "2"
    --
    -- >>> doubleFixedPoint 2 (-2.1)
    -- "-2.10"
    --
    -- >>> doubleFixedPoint 2 0
    -- "0.00"
    {-# INLINE doubleFixedPoint #-}
    doubleFixedPoint ::
      -- | Amount of decimals after point.
      Int ->
      Double ->
      TextBuilder
    doubleFixedPoint :: Int -> Double -> TextBuilder
    doubleFixedPoint (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max Int
    0 -> Int
    decimalPlaces) =
      String -> TextBuilder
    forall a. IsString a => String -> a
    fromString (String -> TextBuilder)
    -> (Double -> String) -> Double -> TextBuilder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . String -> Double -> String
    forall r. PrintfType r => String -> r
    printf (String
    "%." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    decimalPlaces String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "f")

    -- | Double multiplied by 100 with a fixed number of decimal places applied and followed by a percent-sign.
    --
    -- >>> doubleFixedPointPercent 3 0.123456
    -- "12.346%"
    --
    -- >>> doubleFixedPointPercent 0 2
    -- "200%"
    --
    -- >>> doubleFixedPointPercent 0 (-2)
    -- "-200%"
    {-# INLINE doubleFixedPointPercent #-}
    doubleFixedPointPercent ::
      -- | Amount of decimals after point.
      Int ->
      Double ->
      TextBuilder
    doubleFixedPointPercent :: Int -> Double -> TextBuilder
    doubleFixedPointPercent Int
    decimalPlaces Double
    x = Int -> Double -> TextBuilder
    doubleFixedPoint Int
    decimalPlaces (Double
    x Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    100) TextBuilder -> TextBuilder -> TextBuilder
    forall a. Semigroup a => a -> a -> a
    <> TextBuilder
    "%"