lox-go/reporter/main.go
2025-06-08 15:02:35 -04:00

117 lines
2.6 KiB
Go

package reporter
import (
"fmt"
"os"
"strconv"
"git.red-panda.pet/pandaware/lipgloss-catppuccin"
"github.com/charmbracelet/lipgloss"
)
var (
colors = catppuccin.Macchiato
lineStyle = lipgloss.NewStyle().Underline(true)
contextStyle = lipgloss.NewStyle().Foreground(colors.Text)
bracketStyle = lipgloss.NewStyle().Foreground(colors.Overlay2)
messageStyle = lipgloss.NewStyle().Foreground(colors.Text)
levelTagStyles = map[Level]lipgloss.Style{
LevelError: lipgloss.NewStyle().Foreground(colors.Red),
LevelInfo: lipgloss.NewStyle().Foreground(colors.Teal),
LevelDebug: lipgloss.NewStyle().Foreground(colors.Green),
LevelWarn: lipgloss.NewStyle().Foreground(colors.Yellow),
LevelFatal: lipgloss.NewStyle().Foreground(colors.Mauve),
}
)
//go:generate stringer -type Level -trimprefix Level
type Level uint8
const (
LevelDebug Level = iota
LevelInfo
LevelWarn
LevelError
LevelFatal
)
var currentLevel = LevelWarn
func SetLevel(level Level) {
currentLevel = level
}
func bracketed(content, bracketsStr string) string {
brackets := []rune(bracketsStr)
if len(brackets) != 2 {
panic("invariant violation")
}
open := string(brackets[0])
close := string(brackets[1])
return bracketStyle.Render(open) + content + bracketStyle.Render(close)
}
func Log(level Level, component, module string, line int, message string) {
if currentLevel > level {
return
}
ctx := module
if module == "" {
ctx = "<nil>"
}
if line > 0 {
ctx += " at line " + lineStyle.Render(
strconv.Itoa(line),
)
}
levelStr := level.String()
if style, ok := levelTagStyles[level]; ok {
levelStr = style.Render(levelStr)
}
fmt.Printf("%s %s %s: %s\n",
bracketed(levelStr, "[]"),
bracketed(contextStyle.Render(component), "<>"),
bracketed(contextStyle.Render(ctx), "()"),
messageStyle.Render(message),
)
}
func Debug(line int, component, module, message string) {
Log(LevelDebug, component, module, line, message)
}
func Info(line int, component, module, message string) {
Log(LevelInfo, component, module, line, message)
}
func Warn(line int, component, module, message string) {
Log(LevelWarn, component, module, line, message)
}
func Error(line int, component, module, message string) {
Log(LevelError, component, module, line, message)
}
func Fatal(exitCode, line int, component, module, message string) {
Log(LevelFatal, component, module, line, message)
os.Exit(exitCode)
}
// Deprecated: Use `Error` instead
func Err(line int, message string) {
Report(line, "unknown", message)
}
// Deprecated: Use `Error` instead
func Report(line int, where, message string) {
Error(line, "unknown", where, message)
}