{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module OpenAPI.Generate.Log where
import Autodocodec
import Data.List (intersperse)
import Data.Text (Text)
import qualified Data.Text as T
-- | Data type representing the log severities
data LogSeverity
= TraceSeverity
| InfoSeverity
| WarningSeverity
| ErrorSeverity
deriving (Eq, Ord, Bounded, Enum)
instance Show LogSeverity where
show ErrorSeverity = "ERROR"
show WarningSeverity = "WARN"
show InfoSeverity = "INFO"
show TraceSeverity = "TRACE"
instance Read LogSeverity where
readsPrec _ ('E' : 'R' : 'R' : 'O' : 'R' : rest) = [(ErrorSeverity, rest)]
readsPrec _ ('W' : 'A' : 'R' : 'N' : rest) = [(WarningSeverity, rest)]
readsPrec _ ('I' : 'N' : 'F' : 'O' : rest) = [(InfoSeverity, rest)]
readsPrec _ ('T' : 'R' : 'A' : 'C' : 'E' : rest) = [(TraceSeverity, rest)]
readsPrec _ _ = []
instance HasCodec LogSeverity where
codec = shownBoundedEnumCodec
-- | A log entry containing the location within the OpenAPI specification where the message was produced, a severity and the actual message.
data LogEntry = LogEntry
{ logEntryPath :: [Text],
logEntrySeverity :: LogSeverity,
logEntryMessage :: Text
}
deriving (Show, Eq)
-- | The type contained in the writer of the 'OpenAPI.Generate.Monad.Generator' used to collect log entries
type LogEntries = [LogEntry]
-- | Filters and transforms log entries for printing
filterAndTransformLogs :: LogSeverity -> LogEntries -> [Text]
filterAndTransformLogs minimumLogLevel = transformLogs . filterLogs minimumLogLevel
-- | Filters log entries which have a lower log level than provided
filterLogs :: LogSeverity -> LogEntries -> LogEntries
filterLogs minimumLogLevel = filter $ (>= minimumLogLevel) . logEntrySeverity
-- | Transforms 'LogEntries' to a list of 'Text' values for easier printing.
transformLogs :: LogEntries -> [Text]
transformLogs =
fmap
( \LogEntry {..} ->
T.justifyLeft 5 ' ' (T.pack $ show logEntrySeverity) <> " (" <> transformPath logEntryPath <> "): " <> logEntryMessage
)
-- | Transforms the path to a 'Text' representation (parts are seperated with a dot)
transformPath :: [Text] -> Text
transformPath = mconcat . intersperse "."