
Levels.pudu
Pudu93 lines3.1 KB
1/** @Log.Domain.Levels.Module — ranks, names, and monikers of levels */2module PuduLangLog.Domain.Levels34import Std.Char as Char5import Std.List as List6import Std.Map as Map7import Std.Math as Math8import PuduLangLog.Domain.Padding as Padding9import PuduLangLog as Log101112const TITLE: Array[Array[Str]] = [13 ["V", "Vb", "Vrb", "Verb", "Verbo", "Verbos", "Verbose"],14 ["D", "De", "Dbg", "Dbug", "Debug"],15 ["I", "In", "Inf", "Info", "Infor", "Inform", "Informa", "Informat", "Informati", "Informatio", "Information"],16 ["W", "Wn", "Wrn", "Warn", "Warni", "Warnin", "Warning"],17 ["E", "Er", "Err", "Eror", "Error"],18 ["F", "Fa", "Ftl", "Fatl", "Fatal"]19]202122const NAMES: Map[Str, Int] = mapOf([23 ("verbose", 0), ("debug", 1), ("information", 2), ("warning", 3), ("error", 4), ("fatal", 5),24 ("0", 0), ("1", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5)25 ])262728export fn rank(level: Log.Level) -> Int {29 match level {30 case Log.Verbose => 031 case Log.Debug => 132 case Log.Information => 233 case Log.Warning => 334 case Log.Error => 435 case Log.Fatal => 536 }37}383940export fn passes(level: Log.Level, minimum: Log.Level) -> Bool { rank(level) >= rank(minimum) }414243export fn stricter(left: Log.Level, right: Log.Level) -> Log.Level { Log.LEVELS[Math.max(rank(left), rank(right))] }444546export fn name(level: Log.Level) -> Str { monikerOf(level, 99) }474849export fn parse(text: Str) -> Option[Log.Level] {50 let found = Map.get(&NAMES, text.trim().toLower()) ?51 Some(Log.LEVELS[found])52}53545556export fn moniker(level: Log.Level, format: &Option[Str]) -> Str {57 let full = name(level)58 let given = match format {59 case Some(text) => text60 case None => { return full }61 }62 let letters = given.chars()63 let width = match widthOf(&letters) {64 case Some(counted) => counted65 case None => { return Padding.cased(full, format) }66 }67 if width < 1 { return "" }68 let short = monikerOf(level, width)69 match List.first(&letters) {70 case Some('u') => short.toUpper()71 case Some('w') => short.toLower()72 case Some('t') => short73 case _ => full74 }75}767778fn widthOf(letters: &Array[Char]) -> Option[Int] {79 let digits = List.drop(letters, 1)80 if digits.length() < 1 || digits.length() > 2 { return None }81 var width = 082 for digit in digits {83 width = width * 10 + Char.toDigit(digit) ?84 }85 Some(width)86}878889fn monikerOf(level: Log.Level, width: Int) -> Str {90 let names = TITLE[rank(level)]91 names[Math.min(width, names.length()) - 1]92}93