Compare commits

...

8 Commits

Author SHA1 Message Date
fc5803493c added DblPtrIfNotNil
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m31s
2024-06-05 17:53:57 +02:00
a9295bfabf added CoalesceDblPtr
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m37s
2024-06-05 15:10:31 +02:00
12fa53d848 v0.0.466 exerr.Wrap now inherits the Severity of the wrapped error
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m24s
2024-06-03 13:48:30 +02:00
d2bb362135 v0.0.465
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 3m39s
2024-06-03 09:39:57 +02:00
9dd81f6bd5 v0.0.464 improve ZeroLogErrTraces/ZeroLogAllTraces output for empty-message wrapped exerrs
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 4m36s
2024-06-01 02:40:48 +02:00
d2c04afcd5 v0.0.463 Fix SubtractYears
Some checks failed
Build Docker and Deploy / Run goext test-suite (push) Failing after 3m29s
2024-05-29 20:20:01 +02:00
62980e1489 v0.0.462
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 3m32s
2024-05-23 14:37:05 +02:00
59963adf74 v0.0.461
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m17s
2024-05-20 00:52:49 +02:00
15 changed files with 245 additions and 20 deletions

View File

@@ -493,11 +493,12 @@ func (b *Builder) Format(level LogPrintLevel) string {
// If the error is SevErr we also send it to the error-service
func (b *Builder) Fatal(ctxs ...context.Context) {
b.errorData.Severity = SevFatal
for _, dctx := range ctxs {
b.CtxData(MethodFatal, dctx)
}
b.errorData.Severity = SevFatal
b.errorData.Log(stackSkipLogger.WithLevel(zerolog.FatalLevel))
b.errorData.CallListener(MethodFatal)

View File

@@ -56,7 +56,7 @@ func wrapExErr(e *ExErr, msg string, cat ErrorCategory, stacktraceskip int) *ExE
UniqueID: newID(),
Category: cat,
Type: TypeWrap,
Severity: SevErr,
Severity: e.Severity,
Timestamp: time.Now(),
StatusCode: e.StatusCode,
Message: msg,

View File

@@ -84,6 +84,9 @@ func (ee *ExErr) FormatLog(lvl LogPrintLevel) string {
if lvl == LogPrintShort {
msg := ee.Message
if msg == "" {
msg = ee.RecursiveMessage()
}
if ee.OriginalError != nil && ee.OriginalError.Category == CatForeign {
msg = msg + " (" + strings.ReplaceAll(ee.OriginalError.Message, "\n", " ") + ")"
}

View File

@@ -72,20 +72,22 @@ func NewEngine(opt Options) *GinWrapper {
engine.Use(CorsMiddleware())
}
if wrapper.ginDebug {
gin.SetMode(gin.DebugMode)
// do not debug-print routes
gin.DebugPrintRouteFunc = func(_, _, _ string, _ int) {}
if !wrapper.ginDebug {
gin.SetMode(gin.ReleaseMode)
if !wrapper.suppressGinLogs {
ginlogger := gin.Logger()
engine.Use(func(context *gin.Context) {
ginlogger(context)
})
engine.Use(func(context *gin.Context) { ginlogger(context) })
}
} else {
gin.SetMode(gin.DebugMode)
gin.SetMode(gin.ReleaseMode)
// do not debug-print routes
gin.DebugPrintRouteFunc = func(_, _, _ string, _ int) {}
}
return wrapper

10
go.mod
View File

@@ -7,7 +7,7 @@ require (
github.com/glebarez/go-sqlite v1.22.0 // only needed for tests -.-
github.com/jmoiron/sqlx v1.4.0
github.com/rs/xid v1.5.0
github.com/rs/zerolog v1.32.0
github.com/rs/zerolog v1.33.0
go.mongodb.org/mongo-driver v1.15.0
golang.org/x/crypto v0.23.0
golang.org/x/sys v0.20.0
@@ -21,19 +21,19 @@ require (
)
require (
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic v1.11.8 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gabriel-vasile/mimetype v1.4.4 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/go-playground/validator/v10 v10.21.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect

12
go.sum
View File

@@ -18,6 +18,10 @@ github.com/bytedance/sonic v1.11.5 h1:G00FYjjqll5iQ1PYXynbg/hyzqBqavH8Mo9/oTopd9
github.com/bytedance/sonic v1.11.5/go.mod h1:X2PC2giUdj/Cv2lliWFLk6c/DUQok5rViJSemeB0wDw=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic v1.11.7 h1:k/l9p1hZpNIMJSk37wL9ltkcpqLfIho1vYthi4xT2t4=
github.com/bytedance/sonic v1.11.7/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic v1.11.8 h1:Zw/j1KfiS+OYTi9lyB3bb0CFxPJVkM17k1wyDG32LRA=
github.com/bytedance/sonic v1.11.8/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.0/go.mod h1:UmRT+IRTGKz/DAkzcEGzyVqQFJ7H9BqwBO3pm9H/+HY=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
@@ -49,6 +53,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
@@ -73,12 +79,16 @@ github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-playground/validator/v10 v10.21.0 h1:4fZA11ovvtkdgaeev9RGWPgc1uj3H8W+rNYyH/ySBb0=
github.com/go-playground/validator/v10 v10.21.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -162,6 +172,8 @@ github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=

View File

@@ -1,5 +1,5 @@
package goext
const GoextVersion = "0.0.460"
const GoextVersion = "0.0.466"
const GoextVersionTimestamp = "2024-05-20T00:38:04+0200"
const GoextVersionTimestamp = "2024-06-03T13:48:30+0200"

View File

@@ -474,6 +474,17 @@ func ArrAppend[T any](arr []T, add ...T) []T {
return r
}
// ArrPrepend works similar to append(x, y, z) - but doe snot touch the old array and creates a new one
// Also - in contrast to ArrAppend - the add values are inserted at the start of the resulting array (in reverse order)
func ArrPrepend[T any](arr []T, add ...T) []T {
out := make([]T, len(arr)+len(add))
copy(out[len(add):], arr)
for i := 0; i < len(add); i++ {
out[len(add)-i-1] = add[i]
}
return out
}
// ArrCopy does a shallow copy of the 'in' array
func ArrCopy[T any](in []T) []T {
out := make([]T, len(in))

View File

@@ -2,6 +2,7 @@ package langext
import (
"gogs.mikescher.com/BlackForestBytes/goext/tst"
"strings"
"testing"
)
@@ -10,3 +11,13 @@ func TestJoinString(t *testing.T) {
res := JoinString(ids, ",")
tst.AssertEqual(t, res, "1,2,3")
}
func TestArrPrepend(t *testing.T) {
v1 := []string{"1", "2", "3"}
v2 := ArrPrepend(v1, "4", "5", "6")
tst.AssertEqual(t, strings.Join(v1, ""), "123")
tst.AssertEqual(t, strings.Join(v2, ""), "654123")
}

View File

@@ -77,6 +77,14 @@ func Coalesce4Opt[T any](v1 *T, v2 *T, v3 *T, v4 *T) *T {
return v4
}
func CoalesceDblPtr[T any](v1 **T, v2 *T) *T {
if v1 != nil {
return *v1
}
return v2
}
func CoalesceString(s *string, def string) string {
if s == nil {
return def

View File

@@ -22,6 +22,13 @@ func DblPtr[T any](v T) **T {
return &v_
}
func DblPtrIfNotNil[T any](v *T) **T {
if v == nil {
return nil
}
return &v
}
func DblPtrNil[T any]() **T {
var v *T = nil
return &v

View File

@@ -156,7 +156,7 @@ func SubtractYears(t time.Time, yearCount float64, tz *time.Location) time.Time
intCount, floatCount := math.Modf(yearCount)
t.AddDate(-int(intCount), 0, 0)
t = t.AddDate(-int(intCount), 0, 0)
t0 := TimeToYearStart(t, tz)
t1 := TimeToYearEnd(t, tz)
@@ -173,7 +173,7 @@ func AddYears(t time.Time, yearCount float64, tz *time.Location) time.Time {
intCount, floatCount := math.Modf(yearCount)
t.AddDate(int(intCount), 0, 0)
t = t.AddDate(int(intCount), 0, 0)
t0 := TimeToYearStart(t, tz)
t1 := TimeToYearEnd(t, tz)

158
timeext/time_test.go Normal file
View File

@@ -0,0 +1,158 @@
package timeext
import (
"testing"
"time"
)
func TestTimeToDayStart(t *testing.T) {
tz := TimezoneBerlin
tm := time.Date(2022, 1, 1, 13, 14, 15, 0, tz)
expected := time.Date(2022, 1, 1, 0, 0, 0, 0, tz)
result := TimeToDayStart(tm, tz)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestTimeToDayEnd(t *testing.T) {
tz := TimezoneBerlin
tm := time.Date(2022, 1, 1, 13, 14, 15, 0, tz)
expected := time.Date(2022, 1, 2, 0, 0, 0, 0, tz).Add(-1)
result := TimeToDayEnd(tm, tz)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestIsSameDayIncludingDateBoundaries(t *testing.T) {
tz := TimezoneBerlin
t1 := time.Date(2022, 1, 1, 23, 59, 59, 0, tz)
t2 := time.Date(2022, 1, 2, 0, 0, 0, 0, tz)
if !IsSameDayIncludingDateBoundaries(t1, t2, tz) {
t.Errorf("Expected %v and %v to be the same day", t1, t2)
}
}
func TestIsDatePartEqual(t *testing.T) {
tz := TimezoneBerlin
t1 := time.Date(2022, 1, 1, 23, 59, 59, 0, tz)
t2 := time.Date(2022, 1, 1, 0, 0, 0, 0, tz)
if !IsDatePartEqual(t1, t2, tz) {
t.Errorf("Expected %v and %v to have the same date part", t1, t2)
}
}
func TestWithTimePart(t *testing.T) {
tz := TimezoneBerlin
base := time.Date(2022, 1, 1, 0, 0, 0, 0, tz)
expected := time.Date(2022, 1, 1, 13, 14, 15, 0, tz)
result := WithTimePart(base, 13, 14, 15)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestCombineDateAndTime(t *testing.T) {
tz := TimezoneBerlin
d := time.Date(2022, 1, 1, 0, 0, 0, 0, tz)
tm := time.Date(0, 0, 0, 13, 14, 15, 0, tz)
expected := time.Date(2022, 1, 1, 13, 14, 15, 0, tz)
result := CombineDateAndTime(d, tm)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestIsSunday(t *testing.T) {
tz := TimezoneBerlin
tm := time.Date(2022, 1, 2, 0, 0, 0, 0, tz) // 2nd January 2022 is a Sunday
if !IsSunday(tm, tz) {
t.Errorf("Expected %v to be a Sunday", tm)
}
}
func TestDurationFromTime(t *testing.T) {
expected := time.Duration(13*time.Hour + 14*time.Minute + 15*time.Second)
result := DurationFromTime(13, 14, 15)
if result != expected {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestMin(t *testing.T) {
t1 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2022, 1, 2, 0, 0, 0, 0, time.UTC)
expected := t1
result := Min(t1, t2)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestMax(t *testing.T) {
t1 := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
t2 := time.Date(2022, 1, 2, 0, 0, 0, 0, time.UTC)
expected := t2
result := Max(t1, t2)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestUnixFloatSeconds(t *testing.T) {
v := 1640995200.0 // 1st January 2022 00:00:00 UTC in Unix timestamp
expected := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
result := UnixFloatSeconds(v)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestFloorTime(t *testing.T) {
tm := time.Date(2022, 1, 1, 13, 14, 15, 0, time.UTC)
expected := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
result := FloorTime(tm)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestSubtractYears(t *testing.T) {
tz := TimezoneBerlin
tm := time.Date(2022, 1, 1, 0, 0, 0, 0, tz)
expected := time.Date(2021, 1, 1, 0, 0, 0, 0, tz)
result := SubtractYears(tm, 1, tz)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
expected = time.Date(2020, 1, 1, 0, 0, 0, 0, tz)
result = SubtractYears(tm, 2, tz)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
expected = time.Date(2019, 1, 1, 0, 0, 0, 0, tz)
result = SubtractYears(tm, 3, tz)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
expected = time.Date(2025, 1, 1, 0, 0, 0, 0, tz)
result = SubtractYears(tm, -3, tz)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}
func TestAddYears(t *testing.T) {
tz := TimezoneBerlin
tm := time.Date(2022, 1, 1, 0, 0, 0, 0, tz)
expected := time.Date(2023, 1, 1, 0, 0, 0, 0, tz)
result := AddYears(tm, 1, tz)
if !result.Equal(expected) {
t.Errorf("Expected %v but got %v", expected, result)
}
}

View File

@@ -126,6 +126,10 @@ func (b *WPDFBuilder) SetX(x float64) {
b.b.SetX(x)
}
func (b *WPDFBuilder) IncX(dx float64) {
b.b.SetX(b.b.GetX() + dx)
}
func (b *WPDFBuilder) GetX() float64 {
return b.b.GetX()
}

View File

@@ -20,6 +20,7 @@ type PDFCellOpt struct {
textColor *PDFColor
borderColor *PDFColor
fillColor *PDFColor
autoWidthPaddingX *float64
}
func NewPDFCellOpt() *PDFCellOpt {
@@ -113,6 +114,11 @@ func (opt *PDFCellOpt) AutoWidth() *PDFCellOpt {
return opt
}
func (opt *PDFCellOpt) AutoWidthPaddingX(v float64) *PDFCellOpt {
opt.autoWidthPaddingX = &v
return opt
}
func (opt *PDFCellOpt) TextColor(cr, cg, cb int) *PDFCellOpt {
opt.textColor = langext.Ptr(rgbToColor(cr, cg, cb))
return opt
@@ -164,6 +170,7 @@ func (b *WPDFBuilder) Cell(txt string, opts ...*PDFCellOpt) {
var textColor *PDFColor
var borderColor *PDFColor
var fillColor *PDFColor
autoWidthPaddingX := float64(0)
for _, opt := range opts {
width = langext.Coalesce(opt.width, width)
@@ -183,6 +190,7 @@ func (b *WPDFBuilder) Cell(txt string, opts ...*PDFCellOpt) {
textColor = langext.CoalesceOpt(opt.textColor, textColor)
borderColor = langext.CoalesceOpt(opt.borderColor, borderColor)
fillColor = langext.CoalesceOpt(opt.fillColor, fillColor)
autoWidthPaddingX = langext.Coalesce(opt.autoWidthPaddingX, autoWidthPaddingX)
}
if fontNameOverride != nil || fontStyleOverride != nil || fontSizeOverride != nil {
@@ -219,7 +227,7 @@ func (b *WPDFBuilder) Cell(txt string, opts ...*PDFCellOpt) {
}
if autoWidth {
width = b.b.GetStringWidth(txtTR)
width = b.b.GetStringWidth(txtTR) + autoWidthPaddingX
}
b.b.CellFormat(width, height, txtTR, string(border), int(ln), string(align), fill, link, linkStr)