shrun-0.9: A utility program for running shell commands concurrently.
Safe HaskellNone
LanguageGHC2021

Shrun.Utils

Description

Provides utilities.

Synopsis

Text Utils

breakStripPoint :: Text -> Text -> Tuple2 Text Text Source #

Wrapper for Text's breakOn that differs in that:

  1. If the needle is found within the haystack, we do not include it in the second part of the pair.

Examples

Expand
>>> -- Data.Text
>>> T.breakOn "=" "HEY=LISTEN"
("HEY","=LISTEN")
>>> -- Shrun.Utils.Text
>>> breakStripPoint "=" "HEY=LISTEN"
("HEY","LISTEN")

Other examples:

>>> breakStripPoint "=" "HEYLISTEN"
("HEYLISTEN","")
>>> breakStripPoint "=" "=HEYLISTEN"
("","HEYLISTEN")
>>> breakStripPoint "=" "HEYLISTEN="
("HEYLISTEN","")
>>> breakStripPoint "=" "HEY==LISTEN"
("HEY","=LISTEN")

truncateIfNeeded :: Natural -> Text -> Text Source #

For Natural \(n\) and Text \(t = t_0 t_1 \ldots t_m\), truncates \(t\) if \(m > n\). In this case, \(t\) is truncated to \(n - 3\), and an ellipsis ( \(\ldots\) ) is appended. We are left with a string with length exactly \(n\):

\[ t_0 t_1 \ldots t_{n-3} \text{...} \quad \text{-- 3 literal } `\text{.' chars appended} \]

Examples

Expand
>>> truncateIfNeeded 7 "hi"
"hi"
>>> truncateIfNeeded 10 "This is 21 chars long"
"This is..."

stripControlAll :: UnlinedText -> UnlinedText Source #

Strips all control chars, including ansi escape sequences.

Examples

Expand
>>> stripControlAll "foo\ESC[0;3Abar \n baz"
"foobar  baz"

stripControlSmart :: UnlinedText -> UnlinedText Source #

Strips control chars, including most ansi escape sequences. We leave behind SGR ansi escape sequences e.g. text coloring. See https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters.

Examples

Expand
>>> stripControlSmart "foo\ESC[0;3Abar \n baz"
"foobar  baz"
>>> stripControlSmart "foo\ESC[0;3mbar \n baz"
"foo\ESC[0;3mbar  baz"

escapeDoubleQuotes :: Text -> Text Source #

Escape double quotes in strings.

MonadTime Utils

diffTime :: TimeSpec -> TimeSpec -> Natural Source #

For given \(x, y\), returns the absolute difference \(|x - y|\) in seconds.

Examples

Expand
>>> :{
  let t1 = MkTimeSpec 5 0
      -- 20 s + 1 billion ns = 21 s
      t2 = MkTimeSpec 20 1_000_000_000
  in diffTime t1 t2
:}
16

foldMap1 :: (Foldable f, Semigroup s) => (a -> s) -> a -> f a -> s Source #

Relaxes foldMap's Monoid constraint to Semigroup. Requires a starting value. This will have to do until semigroupoids' Foldable1 is in base.

Examples

Expand
>>> foldMap1 @List Sum 0 [1..4]
Sum {getSum = 10}
>>> -- Silly, but demonstrates usage i.e. with non-monoid NonEmpty.
>>> foldMap1 @List (:| []) 1 [2,3,4]
1 :| [2,3,4]

Misc Utils

parseByteText :: Text -> Either Text (Bytes 'B Natural) Source #

Parses bytes with arbitrary units and converts to bytes. First attempts to parse as a Natural so we do not lose precision. If that fails, falls back to Double.

Examples

Expand
>>> parseByteText "120 mb"
Right (MkBytes 120000000)
>>> parseByteText "4.5 terabytes"
Right (MkBytes 4500000000000)

whileM_ :: Monad m => m Bool -> m a -> m () Source #

whileM_ mb ma executes ma as long as mb returns True.

whenLeft :: Applicative f => Either a b -> (a -> f ()) -> f () Source #

Runs the action when it is Left.

untilJust :: Monad m => m (Maybe b) -> m b Source #

Executes the monadic action until we receive a Just, returning the value.

(∸) :: (Ord a, Num a) => a -> a -> a infixl 6 Source #

"monus" i.e. subtraction clamped to zero