From 05580c384a0fba3374aaf87a981812a493e46b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Thu, 28 Dec 2023 01:36:21 +0100 Subject: [PATCH] v0.0.349 --- exerr/gin.go | 13 ++++ ginext/response.go | 165 +++++++++++++++++++++++++++++++++++++++++++-- goextVersion.go | 4 +- gojson/gionic.go | 8 +++ 4 files changed, 183 insertions(+), 7 deletions(-) diff --git a/exerr/gin.go b/exerr/gin.go index 4f2c756..1f4cfaf 100644 --- a/exerr/gin.go +++ b/exerr/gin.go @@ -57,6 +57,19 @@ func (ee *ExErr) toJson(depth int, applyExtendListener bool, outputMeta bool) la return ginJson } +func (ee *ExErr) ToDefaultAPIJson() (string, error) { + + gjr := json.GoJsonRender{Data: ee.ToAPIJson(true, pkgconfig.ExtendedGinOutput, pkgconfig.IncludeMetaInGinOutput), NilSafeSlices: true, NilSafeMaps: true} + + r, err := gjr.RenderString() + + if err != nil { + return "", err + } + + return r, nil +} + // ToAPIJson converts the ExError to a json object // (the same object as used in the Output(gin) method) // diff --git a/ginext/response.go b/ginext/response.go index a427490..7f8789e 100644 --- a/ginext/response.go +++ b/ginext/response.go @@ -5,6 +5,8 @@ import ( "github.com/gin-gonic/gin" "gogs.mikescher.com/BlackForestBytes/goext/exerr" json "gogs.mikescher.com/BlackForestBytes/goext/gojson" + "gogs.mikescher.com/BlackForestBytes/goext/langext" + "os" ) type headerval struct { @@ -18,21 +20,34 @@ type HTTPResponse interface { IsSuccess() bool } +type InspectableHTTPResponse interface { + HTTPResponse + + Statuscode() int + BodyString(g *gin.Context) *string + ContentType() string + Headers() []string +} + type jsonHTTPResponse struct { statusCode int data any headers []headerval } -func (j jsonHTTPResponse) Write(g *gin.Context) { - for _, v := range j.headers { - g.Header(v.Key, v.Val) - } +func (j jsonHTTPResponse) jsonRenderer(g *gin.Context) json.GoJsonRender { var f *string if jsonfilter := g.GetString("goext.jsonfilter"); jsonfilter != "" { f = &jsonfilter } - g.Render(j.statusCode, json.GoJsonRender{Data: j.data, NilSafeSlices: true, NilSafeMaps: true, Filter: f}) + return json.GoJsonRender{Data: j.data, NilSafeSlices: true, NilSafeMaps: true, Filter: f} +} + +func (j jsonHTTPResponse) Write(g *gin.Context) { + for _, v := range j.headers { + g.Header(v.Key, v.Val) + } + g.Render(j.statusCode, j.jsonRenderer(g)) } func (j jsonHTTPResponse) WithHeader(k string, v string) HTTPResponse { @@ -44,6 +59,26 @@ func (j jsonHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } +func (j jsonHTTPResponse) Statuscode() int { + return j.statusCode +} + +func (j jsonHTTPResponse) BodyString(g *gin.Context) *string { + if str, err := j.jsonRenderer(g).RenderString(); err == nil { + return &str + } else { + return nil + } +} + +func (j jsonHTTPResponse) ContentType() string { + return "application/json" +} + +func (j jsonHTTPResponse) Headers() []string { + return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val }) +} + type emptyHTTPResponse struct { statusCode int headers []headerval @@ -65,6 +100,22 @@ func (j emptyHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } +func (j emptyHTTPResponse) Statuscode() int { + return j.statusCode +} + +func (j emptyHTTPResponse) BodyString(*gin.Context) *string { + return nil +} + +func (j emptyHTTPResponse) ContentType() string { + return "" +} + +func (j emptyHTTPResponse) Headers() []string { + return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val }) +} + type textHTTPResponse struct { statusCode int data string @@ -87,6 +138,22 @@ func (j textHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } +func (j textHTTPResponse) Statuscode() int { + return j.statusCode +} + +func (j textHTTPResponse) BodyString(*gin.Context) *string { + return langext.Ptr(j.data) +} + +func (j textHTTPResponse) ContentType() string { + return "text/plain" +} + +func (j textHTTPResponse) Headers() []string { + return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val }) +} + type dataHTTPResponse struct { statusCode int data []byte @@ -110,6 +177,22 @@ func (j dataHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } +func (j dataHTTPResponse) Statuscode() int { + return j.statusCode +} + +func (j dataHTTPResponse) BodyString(*gin.Context) *string { + return langext.Ptr(string(j.data)) +} + +func (j dataHTTPResponse) ContentType() string { + return j.contentType +} + +func (j dataHTTPResponse) Headers() []string { + return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val }) +} + type fileHTTPResponse struct { mimetype string filepath string @@ -138,6 +221,26 @@ func (j fileHTTPResponse) IsSuccess() bool { return true } +func (j fileHTTPResponse) Statuscode() int { + return 200 +} + +func (j fileHTTPResponse) BodyString(*gin.Context) *string { + data, err := os.ReadFile(j.filepath) + if err != nil { + return nil + } + return langext.Ptr(string(data)) +} + +func (j fileHTTPResponse) ContentType() string { + return j.mimetype +} + +func (j fileHTTPResponse) Headers() []string { + return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val }) +} + type downloadDataHTTPResponse struct { statusCode int mimetype string @@ -167,6 +270,22 @@ func (j downloadDataHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } +func (j downloadDataHTTPResponse) Statuscode() int { + return j.statusCode +} + +func (j downloadDataHTTPResponse) BodyString(*gin.Context) *string { + return langext.Ptr(string(j.data)) +} + +func (j downloadDataHTTPResponse) ContentType() string { + return j.mimetype +} + +func (j downloadDataHTTPResponse) Headers() []string { + return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val }) +} + type redirectHTTPResponse struct { statusCode int url string @@ -186,6 +305,22 @@ func (j redirectHTTPResponse) IsSuccess() bool { return j.statusCode >= 200 && j.statusCode <= 399 } +func (j redirectHTTPResponse) Statuscode() int { + return j.statusCode +} + +func (j redirectHTTPResponse) BodyString(*gin.Context) *string { + return nil +} + +func (j redirectHTTPResponse) ContentType() string { + return "" +} + +func (j redirectHTTPResponse) Headers() []string { + return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val }) +} + type jsonAPIErrResponse struct { err *exerr.ExErr headers []headerval @@ -204,6 +339,26 @@ func (j jsonAPIErrResponse) IsSuccess() bool { return false } +func (j jsonAPIErrResponse) Statuscode() int { + return langext.Coalesce(j.err.RecursiveStatuscode(), 0) +} + +func (j jsonAPIErrResponse) BodyString(*gin.Context) *string { + if str, err := j.err.ToDefaultAPIJson(); err == nil { + return &str + } else { + return nil + } +} + +func (j jsonAPIErrResponse) ContentType() string { + return "application/json" +} + +func (j jsonAPIErrResponse) Headers() []string { + return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val }) +} + func Status(sc int) HTTPResponse { return &emptyHTTPResponse{statusCode: sc} } diff --git a/goextVersion.go b/goextVersion.go index 00f5e0b..25aa19c 100644 --- a/goextVersion.go +++ b/goextVersion.go @@ -1,5 +1,5 @@ package goext -const GoextVersion = "0.0.348" +const GoextVersion = "0.0.349" -const GoextVersionTimestamp = "2023-12-27T20:29:37+0100" +const GoextVersionTimestamp = "2023-12-28T01:36:21+0100" diff --git a/gojson/gionic.go b/gojson/gionic.go index 005218c..f8dded6 100644 --- a/gojson/gionic.go +++ b/gojson/gionic.go @@ -37,6 +37,14 @@ func (r GoJsonRender) Render(w http.ResponseWriter) error { return nil } +func (r GoJsonRender) RenderString() (string, error) { + jsonBytes, err := MarshalSafeCollections(r.Data, r.NilSafeSlices, r.NilSafeMaps, r.Indent, r.Filter) + if err != nil { + panic(err) + } + return string(jsonBytes), nil +} + func (r GoJsonRender) WriteContentType(w http.ResponseWriter) { header := w.Header() if val := header["Content-Type"]; len(val) == 0 {