
Theme.pudu
Pudu162 lines4.7 KB
1/** @Log.Sinks.Theme.Palette — terminal colours for each kind of text */2module PuduLangLog.Sinks.Theme34import PuduLangLog.Domain.Display as Display5import PuduLangLog as Log67/** @Log.Sinks.Theme.Palette — the escape sequence that starts each style */8export type Theme = {9 text: Str,10 secondary: Str,11 tertiary: Str,12 invalid: Str,13 nullValue: Str,14 name: Str,15 string: Str,16 number: Str,17 boolean: Str,18 scalar: Str,19 verbose: Str,20 debug: Str,21 information: Str,22 warning: Str,23 error: Str,24 fatal: Str25}262728const RESET: Str = "\u{1b}[0m"293031export fn none() -> Theme {32 Theme{text: "", secondary: "", tertiary: "", invalid: "", nullValue: "", name: "", string: "", number: "", boolean: "", scalar: "", verbose: "", debug: "", information: "", warning: "", error: "", fatal: ""}33}343536export fn literate() -> Theme {37 Theme {38 text: "\u{1b}[38;5;0015m",39 secondary: "\u{1b}[38;5;0007m",40 tertiary: "\u{1b}[38;5;0008m",41 invalid: "\u{1b}[38;5;0011m",42 nullValue: "\u{1b}[38;5;0027m",43 name: "\u{1b}[38;5;0007m",44 string: "\u{1b}[38;5;0045m",45 number: "\u{1b}[38;5;0200m",46 boolean: "\u{1b}[38;5;0027m",47 scalar: "\u{1b}[38;5;0085m",48 verbose: "\u{1b}[38;5;0007m",49 debug: "\u{1b}[38;5;0007m",50 information: "\u{1b}[38;5;0015m",51 warning: "\u{1b}[38;5;0011m",52 error: "\u{1b}[38;5;0015m\u{1b}[48;5;0196m",53 fatal: "\u{1b}[38;5;0015m\u{1b}[48;5;0196m"54 }55}565758export fn grayscale() -> Theme {59 Theme {60 text: "\u{1b}[37;1m",61 secondary: "\u{1b}[37m",62 tertiary: "\u{1b}[30;1m",63 invalid: "\u{1b}[37;1m\u{1b}[47m",64 nullValue: "\u{1b}[1m\u{1b}[37;1m",65 name: "\u{1b}[37m",66 string: "\u{1b}[1m\u{1b}[37;1m",67 number: "\u{1b}[1m\u{1b}[37;1m",68 boolean: "\u{1b}[1m\u{1b}[37;1m",69 scalar: "\u{1b}[1m\u{1b}[37;1m",70 verbose: "\u{1b}[30;1m",71 debug: "\u{1b}[30;1m",72 information: "\u{1b}[37;1m",73 warning: "\u{1b}[37;1m\u{1b}[47m",74 error: "\u{1b}[30m\u{1b}[47m",75 fatal: "\u{1b}[30m\u{1b}[47m"76 }77}787980export fn code() -> Theme {81 Theme {82 text: "\u{1b}[38;5;0253m",83 secondary: "\u{1b}[38;5;0246m",84 tertiary: "\u{1b}[38;5;0242m",85 invalid: "\u{1b}[33;1m",86 nullValue: "\u{1b}[38;5;0038m",87 name: "\u{1b}[38;5;0081m",88 string: "\u{1b}[38;5;0216m",89 number: "\u{1b}[38;5;151m",90 boolean: "\u{1b}[38;5;0038m",91 scalar: "\u{1b}[38;5;0079m",92 verbose: "\u{1b}[37m",93 debug: "\u{1b}[37m",94 information: "\u{1b}[37;1m",95 warning: "\u{1b}[38;5;0229m",96 error: "\u{1b}[38;5;0197m\u{1b}[48;5;0238m",97 fatal: "\u{1b}[38;5;0197m\u{1b}[48;5;0238m"98 }99}100101102export fn sixteen() -> Theme {103 Theme {104 text: "",105 secondary: "",106 tertiary: "",107 invalid: "\u{1b}[33m",108 nullValue: "\u{1b}[34m",109 name: "",110 string: "\u{1b}[36m",111 number: "\u{1b}[35m",112 boolean: "\u{1b}[34m",113 scalar: "\u{1b}[32m",114 verbose: "",115 debug: "\u{1b}[1m",116 information: "\u{1b}[36;1m",117 warning: "\u{1b}[33;1m",118 error: "\u{1b}[31;1m",119 fatal: "\u{1b}[31;1m"120 }121}122123124fn startOf(theme: &Theme, style: &Display.Style) -> Str {125 match style {126 case Display.Plain => theme.text127 case Display.Secondary => theme.secondary128 case Display.Tertiary => theme.tertiary129 case Display.Invalid => theme.invalid130 case Display.NullStyle => theme.nullValue131 case Display.NameStyle => theme.name132 case Display.StringStyle => theme.string133 case Display.NumberStyle => theme.number134 case Display.BooleanStyle => theme.boolean135 case Display.ScalarStyle => theme.scalar136 case Display.LevelStyle(level) => match level {137 case Log.Verbose => theme.verbose138 case Log.Debug => theme.debug139 case Log.Information => theme.information140 case Log.Warning => theme.warning141 case Log.Error => theme.error142 case Log.Fatal => theme.fatal143 }144 }145}146147148149export fn paint(theme: &Theme, pieces: &Array[Display.Piece]) -> Str {150 var out: Array[Str] = []151 for piece in pieces {152 let start = startOf(theme, &piece.style)153 if start.isEmpty() || piece.text.isEmpty() {154 out = out.push(piece.text)155 } else {156 let body = piece.text.split("\n").map(|line: Str| if line.isEmpty() { line } else { start + line + RESET })157 out = out.push(body.join("\n"))158 }159 }160 out.join("")161}162