buildbox-2.2.1.2: BuildBox/Data/Log.hs
{-# LANGUAGE TypeSynonymInstances #-}
-- | When the output of a command is long, keeping it as a `String` is a bad idea.
module BuildBox.Data.Log
( Log
, Line
, empty
, null
, toString
, fromString
, (<|)
, (|>)
, (><)
, firstLines
, lastLines)
where
import Data.Sequence (Seq)
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Sequence as Seq
import qualified Data.Foldable as F
import Prelude hiding (null)
-- | A sequence of lines, without newline charaters on the end.
type Log = Seq Line
type Line = Text
-- | O(1) No logs here.
empty :: Log
empty = Seq.empty
-- | O(1) Check if the log is empty.
null :: Log -> Bool
null = Seq.null
-- | O(n) Convert a `Log` to a `String`.
toString :: Log -> String
toString ll
= Text.unpack
$ Text.intercalate (Text.pack "\n")
$ F.toList ll
-- | O(n) Convert a `String` to a `Log`.
fromString :: String -> Log
fromString str
= Seq.fromList
$ Text.lines
$ Text.pack str
-- | O(1) Add a `Line` to the start of a `Log`.
(<|):: Line -> Log -> Log
(<|) = (Seq.<|)
-- | O(1) Add a `Line` to the end of a `Log`.
(|>) :: Log -> Line -> Log
(|>) = (Seq.|>)
-- | O(log(min(n1,n2))) Concatenate two `Log`s.
(><) :: Log -> Log -> Log
(><) = (Seq.><)
-- | O(n) Take the first m lines from a log
firstLines :: Int -> Log -> Log
firstLines m ll
= Seq.take m ll
-- | O(n) Take the last m lines from a log
lastLines :: Int -> Log -> Log
lastLines m ll
= Seq.drop (Seq.length ll - m) ll