diff --git a/cerror/code.go b/cerror/code.go new file mode 100644 index 0000000..ac0fa48 --- /dev/null +++ b/cerror/code.go @@ -0,0 +1,36 @@ +package cerror + +import ( + "git.twelvetwelve.org/library/core/log" +) + +var codes = make(map[string]*Code) + +type Code struct { + code string +} + +func (c *Code) Error() string { + return c.code +} + +func NewCode(urn string) *Code { + if _, ok := codes[urn]; ok { + log.Panicf("error code %s already exists", urn) + } + + code := &Code{ + code: urn, + } + codes[urn] = code + return code +} + +func GetCode(urn string) *Code { + if code, ok := codes[urn]; ok { + return code + } + + log.Panicf("error code %s does not exist", urn) + return nil +} diff --git a/cerror/error.go b/cerror/error.go new file mode 100644 index 0000000..8e63c90 --- /dev/null +++ b/cerror/error.go @@ -0,0 +1,33 @@ +package cerror + +import ( + "fmt" +) + +type Error struct { + code *Code + msg string + kv map[string]interface{} +} + +func (e *Error) Code() *Code { + return e.code +} + +func (e *Error) Error() string { + return fmt.Sprintf("%s:%s", e.code, e.msg) +} + +func (e *Error) KV(k string, v interface{}) { + e.kv[k] = v +} + +func New(code *Code, message string) *Error { + e := &Error{ + code: code, + msg: message, + kv: make(map[string]interface{}), + } + + return e +} diff --git a/cerror/error_test.go b/cerror/error_test.go new file mode 100644 index 0000000..2fa8f01 --- /dev/null +++ b/cerror/error_test.go @@ -0,0 +1,23 @@ +package cerror + +import ( + "testing" + + "git.twelvetwelve.org/library/core/testutil/assert" +) + +func TestError_Errors(t *testing.T) { + c := NewCode("org.twelvetwelve.one") + assert.NotNil(t, c) + + e := New(c, "something went wrong") + assert.NotNil(t, e) + + assert.Equal(t, e.Code(), c) + assert.WillPanic(t, func() { _ = NewCode("org.twelvetwelve.one") }) + assert.WillPanic(t, func() { _ = GetCode("org.twelvetwelve.two") }) + + c2 := NewCode("org.twelvetwelve.two") + assert.NotNil(t, c2) + assert.NotEqual(t, c, c2) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9748bfb --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.twelvetwelve.org/library/core + +go 1.20 diff --git a/log/default.go b/log/default.go new file mode 100644 index 0000000..e707712 --- /dev/null +++ b/log/default.go @@ -0,0 +1,42 @@ +package log + +var Default = &Log{ + fmtTime: "2006-01-02 15:04:05", + level: LogAll, +} + +func Printf(s string, v ...interface{}) { + Default.Printf(s, v...) +} + +func Panicf(s string, v ...interface{}) { + Default.Panicf(s, v...) +} + +func Fatalf(s string, v ...interface{}) { + Default.Fatalf(s, v...) +} + +func Infof(s string, v ...interface{}) { + Default.Infof(s, v...) +} + +func Eventf(s string, v ...interface{}) { + Default.Eventf(s, v...) +} + +func Warnf(s string, v ...interface{}) { + Default.Warnf(s, v...) +} + +func Debugf(s string, v ...interface{}) { + Default.Debugf(s, v...) +} + +func Highlightf(s string, v ...interface{}) { + Default.Highlightf(s, v...) +} + +func Errorf(s string, v ...interface{}) { + Default.Errorf(s, v...) +} diff --git a/log/interface.go b/log/interface.go new file mode 100644 index 0000000..d56590c --- /dev/null +++ b/log/interface.go @@ -0,0 +1,13 @@ +package log + +type Logger interface { + Printf(s string, v ...interface{}) + Panicf(s string, v ...interface{}) + Fatalf(s string, v ...interface{}) + Infof(s string, v ...interface{}) + Eventf(s string, v ...interface{}) + Warnf(s string, v ...interface{}) + Debugf(s string, v ...interface{}) + Highlightf(s string, v ...interface{}) + Errorf(s string, v ...interface{}) +} diff --git a/log/log.go b/log/log.go new file mode 100644 index 0000000..6aff37a --- /dev/null +++ b/log/log.go @@ -0,0 +1,97 @@ +package log + +import ( + "fmt" + "os" + "time" +) + +const ( + ColorReset = "\033[0m" + ColorRed = "\033[31m" + ColorGreen = "\033[32m" + ColorYellow = "\033[33m" + ColorCyan = "\033[36m" + ColorGray = "\033[2;37m" +) + +const ( + LogError = 1 << iota + LogWarn + LogEvent + LogInfo + LogHighlight + LogPrint + LogDebug + + LogAll = LogError | LogWarn | LogEvent | LogInfo | LogHighlight | LogPrint | LogDebug +) + +type Log struct { + fmtTime string + level uint32 +} + +func (l *Log) Printf(s string, v ...interface{}) { + if l.level&LogPrint == LogPrint { + l.ColorPrint(ColorGray, fmt.Sprintf(s, v...)) + } +} + +func (l *Log) Panicf(s string, v ...interface{}) { + panic(fmt.Sprintf(s, v...)) +} + +func (l *Log) Fatalf(s string, v ...interface{}) { + l.ColorPrint(ColorRed, fmt.Sprintf(s, v...)) + os.Exit(1) +} + +func (l *Log) Infof(s string, v ...interface{}) { + if l.level&LogInfo == LogInfo { + l.ColorPrint(ColorReset, fmt.Sprintf(s, v...)) + } +} + +func (l *Log) Eventf(s string, v ...interface{}) { + if l.level&LogEvent == LogEvent { + l.ColorPrint(ColorCyan, fmt.Sprintf(s, v...)) + } +} + +func (l *Log) Warnf(s string, v ...interface{}) { + if l.level&LogWarn == LogWarn { + l.ColorPrint(ColorYellow, fmt.Sprintf(s, v...)) + } +} + +func (l *Log) Debugf(s string, v ...interface{}) { + if l.level&LogDebug == LogDebug { + l.ColorPrint(ColorGray, fmt.Sprintf(s, v...)) + } +} + +func (l *Log) Highlightf(s string, v ...interface{}) { + if l.level&LogHighlight == LogHighlight { + l.ColorPrint(ColorGreen, fmt.Sprintf(s, v...)) + } +} + +func (l *Log) Errorf(s string, v ...interface{}) { + if l.level&LogHighlight == LogHighlight { + l.ColorPrint(ColorRed, fmt.Sprintf(s, v...)) + } +} + +func (l *Log) ColorPrint(color string, s string) { + now := time.Now() // get this early. + fmt.Fprintf(os.Stdout, "%s | %s%s%s", now.Format(l.fmtTime), color, s, ColorReset) +} + +func (l *Log) SetLevel(level uint32) { + l.level = level +} + +func (l *Log) SetTimeFormat(fmt string) { + l.fmtTime = fmt +} diff --git a/testutil/assert/asserts.go b/testutil/assert/asserts.go new file mode 100644 index 0000000..72e6800 --- /dev/null +++ b/testutil/assert/asserts.go @@ -0,0 +1,30 @@ +package assert + +import ( + "testing" +) + +func WillPanic(t *testing.T, f func()) { + t.Helper() + defer func() { _ = recover() }() + f() + t.Fatalf("should have panicked") +} + +func Equal(t *testing.T, expect, check interface{}) { + if expect != check { + t.Fatalf("%v:%v not equal", expect, check) + } +} + +func NotEqual(t *testing.T, expect, check interface{}) { + if expect == check { + t.Fatalf("%v:%v equal", expect, check) + } +} + +func NotNil(t *testing.T, v interface{}) { + if v == nil { + t.Fatalf("nil") + } +}