{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {- | Module : System.MemInfo.Print Copyright : (c) 2022 Tim Emiola Maintainer : Tim Emiola SPDX-License-Identifier: BSD3 This module provides functions that format the output of the @printmem@ command -} module System.MemInfo.Print ( AsCmdName (..), fmtAsHeader, fmtOverall, fmtMemUsage, ) where import qualified Data.Text as Text import Fmt ( fixedF, padBothF, padLeftF, padRightF, (+|), (+||), (|+), (|++|), (||+), ) import System.MemInfo.Prelude import System.MemInfo.Proc (MemUsage (..)) {- | Generates the text of a row displaying the metrics for a single command in the memory report -} fmtMemUsage :: AsCmdName a => Bool -> a -> MemUsage -> Text fmtMemUsage showSwap name ct = let padl = padLeftF columnWidth ' ' . fmtMem private = padl $ muPrivate ct - muShared ct shared = padl $ muShared ct all' = padl $ muPrivate ct swap' = padl $ muSwap ct name' = cmdWithCount name $ muCount ct ram = "" +| private |+ " + " +| shared |+ " = " +| all' |+ "" label = "" +| name' |+ "" in if showSwap then ram <> ("" +| swap' |+ "\t") <> label else ram <> "\t" <> label -- | Generates the text showing the overall memory in the memory report fmtOverall :: Bool -> (Int, Int) -> Text fmtOverall showSwap (private, swap) = let rimLength = if showSwap then 46 else 36 gapLength = 26 top = Text.replicate rimLength "-" gap = Text.replicate gapLength " " bottom = Text.replicate rimLength "=" padl = padLeftF columnWidth ' ' . fmtMem withSwap = "" +| gap |++| padl private |++| padl swap |+ "" noSwap = "" +| gap |++| padl private |+ "" out = if showSwap then withSwap else noSwap in Text.unlines [top, out, bottom] data Power = Ki | Mi | Gi | Ti deriving (Eq, Show, Ord, Enum, Bounded) fmtMem :: Int -> Text fmtMem = fmtMem' Ki . fromIntegral columnWidth :: Int columnWidth = 10 fmtMem' :: Power -> Float -> Text fmtMem' = let doFmt p x = "" +| fixedF 1 x |+ " " +|| p ||+ "B" go p x | p == maxBound = doFmt p x go p x | x > 1000 = fmtMem' (succ p) (x / 1024) go p x = doFmt p x in go hdrPrivate, hdrShared, hdrRamUsed, hdrSwapUsed, hdrProgram :: Text hdrPrivate = "Private" hdrShared = "Shared" hdrRamUsed = "RAM Used" hdrSwapUsed = "Swap Used" hdrProgram = "Program" -- | Generates the text of the printed header of the memory report fmtAsHeader :: Bool -> Text fmtAsHeader showSwap = let padb = padBothF columnWidth ' ' padr = padRightF columnWidth ' ' padl = padLeftF columnWidth ' ' private = padb hdrPrivate shared = padb hdrShared all' = padl hdrRamUsed name' = padr hdrProgram swap' = padl hdrSwapUsed ram = "" +| private |+ " + " +| shared |+ " = " +| all' |+ "" label = "" +| name' |+ "" in if showSwap then ram <> ("" +| swap' |+ "\t") <> label else ram <> "\t" <> label cmdWithCount :: AsCmdName a => a -> Int -> Text cmdWithCount cmd count = "" +| asCmdName cmd |+ " (" +| count |+ ")" -- | Represents a label that is as the command name in the report output class AsCmdName a where -- Convert the label to text for output asCmdName :: a -> Text instance AsCmdName Text where asCmdName = id instance AsCmdName (ProcessID, Text) where asCmdName (pid, name) = "" +| name |+ " [" +| toInteger pid |+ "]"