{-# LANGUAGE TypeSynonymInstances #-}-- | When the output of a command is long, keeping it as a `String` is a bad idea.moduleBuildBox.Data.Log(Log,Line,empty,null,toString,fromString,(<|),(|>),(><),firstLines,lastLines)whereimportData.ByteString.Char8(ByteString)importData.Sequence(Seq)importqualifiedData.ByteString.Char8asBSimportqualifiedData.SequenceasSeqimportqualifiedData.FoldableasFimportPreludehiding(null)-- | A sequence of lines, without newline charaters on the end.typeLog=SeqLinetypeLine=ByteString-- | O(1) No logs here.empty::Logempty=Seq.empty-- | O(1) Check if the log is empty.null::Log->Boolnull=Seq.null-- | O(n) Convert a `Log` to a `String`.toString::Log->StringtoStringll=BS.unpack$BS.intercalate(BS.pack"\n")$F.toListll-- | O(n) Convert a `String` to a `Log`.fromString::String->LogfromStringstr=Seq.fromList$BS.splitWith(=='\n')$BS.packstr-- | 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 logfirstLines::Int->Log->LogfirstLinesmll=Seq.takemll-- | O(n) Take the last m lines from a loglastLines::Int->Log->LoglastLinesmll=Seq.drop(Seq.lengthll-m)ll