removed intermediate /internal directory
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
bodyRes struct {
|
||||
body io.ReadCloser
|
||||
res Response
|
||||
}
|
||||
)
|
||||
|
||||
var _ Response = bodyRes{}
|
||||
|
||||
func Body(body io.ReadCloser) Response {
|
||||
return bodyRes{
|
||||
body: body,
|
||||
}
|
||||
}
|
||||
|
||||
func (b bodyRes) String() string {
|
||||
if b.res != nil {
|
||||
return fmt.Sprintf(`{"body": %q, "nested": %s}`, b.body, b.res)
|
||||
}
|
||||
return fmt.Sprintf(`{"body": %q}`, b.body)
|
||||
}
|
||||
|
||||
func (b bodyRes) wrap(res Response) Response {
|
||||
b.res = res
|
||||
return b
|
||||
}
|
||||
|
||||
func (b bodyRes) Status(code int) Response {
|
||||
return Status(code).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) Redirect(code redirect.Code, to string) Response {
|
||||
return Redirect(code, to).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HTML(body []byte) Response {
|
||||
return HTML(body).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) JSON(body any) Response {
|
||||
return JSON(body).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) Body(body io.ReadCloser) Response {
|
||||
b.body = body
|
||||
return b
|
||||
}
|
||||
|
||||
func (b bodyRes) Cookie(ck http.Cookie) Response {
|
||||
return Cookie(ck).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXPushURL(v string) Response {
|
||||
return HXPushURL(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXLocation(v string) Response {
|
||||
return HXLocation(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXPushUrl(v string) Response {
|
||||
return HXPushUrl(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXRedirect(v string) Response {
|
||||
return HXRedirect(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXRefresh(v string) Response {
|
||||
return HXRefresh(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXReplaceUrl(v string) Response {
|
||||
return HXReplaceUrl(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXReswap(v string) Response {
|
||||
return HXReswap(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXRetarget(v string) Response {
|
||||
return HXRetarget(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXReselect(v string) Response {
|
||||
return HXReselect(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXTrigger(v string) Response {
|
||||
return HXTrigger(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXTriggerAfterSettle(v string) Response {
|
||||
return HXTriggerAfterSettle(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) HXTriggerAfterSwap(v string) Response {
|
||||
return HXTriggerAfterSwap(v).wrap(b)
|
||||
}
|
||||
|
||||
func (b bodyRes) GetStatus() (int, bool) {
|
||||
if b.res == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return b.res.GetStatus()
|
||||
}
|
||||
|
||||
func (b bodyRes) getHeaders() [][2]string {
|
||||
if b.res != nil {
|
||||
return b.res.getHeaders()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b bodyRes) GetRedirect() (code redirect.Code, to string, ok bool) {
|
||||
if b.res == nil {
|
||||
return 0, "", false
|
||||
}
|
||||
|
||||
return b.res.GetRedirect()
|
||||
}
|
||||
|
||||
func (b bodyRes) getBody() (body io.ReadCloser, ok bool, err error) {
|
||||
return b.body, true, nil
|
||||
}
|
||||
|
||||
func (b bodyRes) getCookies() []http.Cookie {
|
||||
if b.res != nil {
|
||||
return b.res.getCookies()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b bodyRes) getContentType() (contentType string, ok bool) {
|
||||
if b.res != nil {
|
||||
return b.res.getContentType()
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
cookieRes struct {
|
||||
cookie http.Cookie
|
||||
res Response
|
||||
}
|
||||
)
|
||||
|
||||
var _ Response = cookieRes{}
|
||||
|
||||
func Cookie(c http.Cookie) Response {
|
||||
return cookieRes{
|
||||
cookie: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (c cookieRes) String() string {
|
||||
if c.res != nil {
|
||||
return fmt.Sprintf(`{"cookie": %q, "nested": %s}`, &c.cookie, c.res)
|
||||
}
|
||||
return fmt.Sprintf(`{"cookie": %q}`, &c.cookie)
|
||||
}
|
||||
|
||||
func (c cookieRes) wrap(res Response) Response {
|
||||
c.res = res
|
||||
return c
|
||||
}
|
||||
|
||||
func (c cookieRes) Status(code int) Response {
|
||||
return Status(code).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) Redirect(code redirect.Code, to string) Response {
|
||||
return Redirect(code, to).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HTML(body []byte) Response {
|
||||
return HTML(body).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) JSON(body any) Response {
|
||||
return JSON(body).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) Body(body io.ReadCloser) Response {
|
||||
return Body(body).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) Cookie(ck http.Cookie) Response {
|
||||
return Cookie(ck).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXPushURL(v string) Response {
|
||||
return HXPushURL(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXLocation(v string) Response {
|
||||
return HXLocation(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXPushUrl(v string) Response {
|
||||
return HXPushUrl(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXRedirect(v string) Response {
|
||||
return HXRedirect(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXRefresh(v string) Response {
|
||||
return HXRefresh(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXReplaceUrl(v string) Response {
|
||||
return HXReplaceUrl(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXReswap(v string) Response {
|
||||
return HXReswap(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXRetarget(v string) Response {
|
||||
return HXRetarget(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXReselect(v string) Response {
|
||||
return HXReselect(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXTrigger(v string) Response {
|
||||
return HXTrigger(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXTriggerAfterSettle(v string) Response {
|
||||
return HXTriggerAfterSettle(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) HXTriggerAfterSwap(v string) Response {
|
||||
return HXTriggerAfterSwap(v).wrap(c)
|
||||
}
|
||||
|
||||
func (c cookieRes) GetStatus() (int, bool) {
|
||||
if c.res == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return c.res.GetStatus()
|
||||
}
|
||||
|
||||
func (c cookieRes) getHeaders() [][2]string {
|
||||
if c.res != nil {
|
||||
return c.res.getHeaders()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c cookieRes) GetRedirect() (code redirect.Code, to string, ok bool) {
|
||||
if c.res == nil {
|
||||
return 0, "", false
|
||||
}
|
||||
|
||||
return c.res.GetRedirect()
|
||||
}
|
||||
|
||||
func (c cookieRes) getBody() (body io.ReadCloser, ok bool, err error) {
|
||||
if c.res == nil {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
return c.res.getBody()
|
||||
}
|
||||
|
||||
func (c cookieRes) getCookies() []http.Cookie {
|
||||
if c.res != nil {
|
||||
return append(c.res.getCookies(), c.cookie)
|
||||
}
|
||||
|
||||
return []http.Cookie{c.cookie}
|
||||
}
|
||||
|
||||
func (c cookieRes) getContentType() (contentType string, ok bool) {
|
||||
if c.res != nil {
|
||||
return c.res.getContentType()
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"ruben/inventory2/consts"
|
||||
)
|
||||
|
||||
type (
|
||||
// ErrorResponse is an error
|
||||
ErrorResponse struct {
|
||||
err error
|
||||
msg string
|
||||
status int
|
||||
html []byte
|
||||
}
|
||||
)
|
||||
|
||||
// Constructors
|
||||
|
||||
func Errorf(format string, args ...any) ErrorResponse {
|
||||
return ErrorResponse{
|
||||
err: fmt.Errorf(format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
func BadRequest() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusBadRequest,
|
||||
}
|
||||
}
|
||||
|
||||
func NotFound() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusNotFound,
|
||||
}
|
||||
}
|
||||
|
||||
func Unauthorized() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusUnauthorized,
|
||||
}
|
||||
}
|
||||
|
||||
func Forbidden() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusForbidden,
|
||||
}
|
||||
}
|
||||
|
||||
func Conflict() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusConflict,
|
||||
}
|
||||
}
|
||||
|
||||
// builder pattern implementation
|
||||
|
||||
func (e ErrorResponse) Msg(msg string) ErrorResponse {
|
||||
e.msg = msg
|
||||
return e
|
||||
}
|
||||
|
||||
func (e ErrorResponse) Msgf(format string, args ...any) ErrorResponse {
|
||||
e.msg = fmt.Sprintf(format, args...)
|
||||
return e
|
||||
}
|
||||
|
||||
func (e ErrorResponse) Status(status int) ErrorResponse {
|
||||
e.status = status
|
||||
return e
|
||||
}
|
||||
|
||||
func (e ErrorResponse) Wrap(err error) ErrorResponse {
|
||||
e.err = err
|
||||
return e
|
||||
}
|
||||
|
||||
func (e ErrorResponse) HTML(h []byte) ErrorResponse {
|
||||
e.html = h
|
||||
return e
|
||||
}
|
||||
|
||||
// error implementation
|
||||
|
||||
func (e ErrorResponse) Error() string {
|
||||
parts := make([]string, 0, 3)
|
||||
|
||||
if e.msg != "" {
|
||||
parts = append(parts, e.msg)
|
||||
} else if e.status != 0 {
|
||||
parts = append(parts, fmt.Sprintf("status = %d", e.status))
|
||||
}
|
||||
if e.err != nil {
|
||||
parts = append(parts, e.err.Error())
|
||||
}
|
||||
|
||||
if len(parts) == 0 {
|
||||
return "status = 500"
|
||||
}
|
||||
|
||||
return strings.Join(parts, ": ")
|
||||
}
|
||||
|
||||
func (e ErrorResponse) Unwrap() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
// nested response value resolution
|
||||
|
||||
func (e ErrorResponse) GetStatus() (int, bool) {
|
||||
if e.status != 0 {
|
||||
return e.status, true
|
||||
}
|
||||
|
||||
ce, ok := GetError(e.err)
|
||||
if ok {
|
||||
return ce.GetStatus()
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (e ErrorResponse) GetMsg() (string, bool) {
|
||||
if e.msg != "" {
|
||||
return e.msg, true
|
||||
}
|
||||
|
||||
ce, ok := GetError(e.err)
|
||||
if ok {
|
||||
return ce.GetMsg()
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (e ErrorResponse) GetHTML() ([]byte, bool) {
|
||||
if len(e.html) != 0 {
|
||||
return e.html, true
|
||||
}
|
||||
|
||||
ce, ok := GetError(e.err)
|
||||
if ok {
|
||||
return ce.GetHTML()
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func GetError(err error) (e ErrorResponse, ok bool) {
|
||||
if ok = errors.As(err, &e); ok {
|
||||
return e, true
|
||||
}
|
||||
var ptr *ErrorResponse
|
||||
if ok = errors.As(err, &ptr); ok {
|
||||
return *ptr, true
|
||||
}
|
||||
return e, ok
|
||||
}
|
||||
|
||||
// error wrapping utilities
|
||||
|
||||
func ErrorFromConstant(err error) error {
|
||||
cerr := err
|
||||
for cerr != nil {
|
||||
switch cerr {
|
||||
case consts.ErrNotFound:
|
||||
return NotFound()
|
||||
case consts.ErrConflict:
|
||||
return Conflict()
|
||||
}
|
||||
|
||||
uerr, ok := cerr.(interface {
|
||||
Unwrap() error
|
||||
})
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
|
||||
cerr = uerr.Unwrap()
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type (
|
||||
HandlerFunc = func(c *gin.Context) (Response, error)
|
||||
|
||||
Middleware = func(HandlerFunc) HandlerFunc
|
||||
|
||||
responseKey struct{}
|
||||
)
|
||||
|
||||
func Handler(f HandlerFunc) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
res, err := f(c)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
c.Abort()
|
||||
} else if res != nil {
|
||||
c.Set(responseKey{}, res)
|
||||
c.Abort()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
headerRes struct {
|
||||
name string
|
||||
value string
|
||||
res Response
|
||||
}
|
||||
)
|
||||
|
||||
var _ Response = headerRes{}
|
||||
|
||||
func header(name, value string) Response {
|
||||
return headerRes{
|
||||
name: name,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func HXPushURL(v string) Response {
|
||||
return header("HX-Push-Url", v)
|
||||
}
|
||||
|
||||
func HXLocation(v string) Response {
|
||||
return header("HX-Location", v)
|
||||
}
|
||||
|
||||
func HXPushUrl(v string) Response {
|
||||
return header("HX-Push-Url", v)
|
||||
}
|
||||
|
||||
func HXRedirect(v string) Response {
|
||||
return header("HX-Redirect", v)
|
||||
}
|
||||
|
||||
func HXRefresh(v string) Response {
|
||||
return header("HX-Refresh", v)
|
||||
}
|
||||
|
||||
func HXReplaceUrl(v string) Response {
|
||||
return header("HX-Replace-Url", v)
|
||||
}
|
||||
|
||||
func HXReswap(v string) Response {
|
||||
return header("HX-Reswap", v)
|
||||
}
|
||||
|
||||
func HXRetarget(v string) Response {
|
||||
return header("HX-Retarget", v)
|
||||
}
|
||||
|
||||
func HXReselect(v string) Response {
|
||||
return header("HX-Reselect", v)
|
||||
}
|
||||
|
||||
func HXTrigger(v string) Response {
|
||||
return header("HX-Trigger", v)
|
||||
}
|
||||
|
||||
func HXTriggerAfterSettle(v string) Response {
|
||||
return header("HX-Trigger-After-Settle", v)
|
||||
}
|
||||
|
||||
func HXTriggerAfterSwap(v string) Response {
|
||||
return header("HX-Trigger-After-Swap", v)
|
||||
}
|
||||
|
||||
func (h headerRes) String() string {
|
||||
if h.res != nil {
|
||||
return fmt.Sprintf(`{"header": {"name": %q, "value": %q}, "nested": %s}`, h.name, h.value, h.res)
|
||||
}
|
||||
return fmt.Sprintf(`{"header": {"name": %q, "value": %q}}`, h.name, h.value)
|
||||
}
|
||||
|
||||
func (h headerRes) wrap(res Response) Response {
|
||||
h.res = res
|
||||
return h
|
||||
}
|
||||
|
||||
func (h headerRes) Status(code int) Response {
|
||||
return Status(code).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) Header(name, value string) Response {
|
||||
h.name = name
|
||||
h.value = value
|
||||
return h
|
||||
}
|
||||
|
||||
func (h headerRes) Redirect(code redirect.Code, to string) Response {
|
||||
return Redirect(code, to).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HTML(body []byte) Response {
|
||||
return HTML(body).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) JSON(body any) Response {
|
||||
return JSON(body).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) Body(body io.ReadCloser) Response {
|
||||
return Body(body).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) Cookie(ck http.Cookie) Response {
|
||||
return Cookie(ck).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXPushURL(v string) Response {
|
||||
return HXPushURL(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXLocation(v string) Response {
|
||||
return HXLocation(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXPushUrl(v string) Response {
|
||||
return HXPushUrl(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXRedirect(v string) Response {
|
||||
return HXRedirect(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXRefresh(v string) Response {
|
||||
return HXRefresh(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXReplaceUrl(v string) Response {
|
||||
return HXReplaceUrl(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXReswap(v string) Response {
|
||||
return HXReswap(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXRetarget(v string) Response {
|
||||
return HXRetarget(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXReselect(v string) Response {
|
||||
return HXReselect(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXTrigger(v string) Response {
|
||||
return HXTrigger(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXTriggerAfterSettle(v string) Response {
|
||||
return HXTriggerAfterSettle(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) HXTriggerAfterSwap(v string) Response {
|
||||
return HXTriggerAfterSwap(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h headerRes) GetStatus() (int, bool) {
|
||||
if h.res == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return h.res.GetStatus()
|
||||
}
|
||||
|
||||
func (h headerRes) getHeaders() [][2]string {
|
||||
hdr := [2]string{h.name, h.value}
|
||||
if h.res == nil {
|
||||
return [][2]string{hdr}
|
||||
}
|
||||
|
||||
return append(h.res.getHeaders(), hdr)
|
||||
}
|
||||
|
||||
func (h headerRes) GetRedirect() (code redirect.Code, to string, ok bool) {
|
||||
if h.res == nil {
|
||||
return 0, "", false
|
||||
}
|
||||
|
||||
return h.res.GetRedirect()
|
||||
}
|
||||
|
||||
func (h headerRes) getBody() (body io.ReadCloser, ok bool, err error) {
|
||||
if h.res == nil {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
return h.res.getBody()
|
||||
}
|
||||
|
||||
func (h headerRes) getCookies() []http.Cookie {
|
||||
if h.res != nil {
|
||||
return h.res.getCookies()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h headerRes) getContentType() (contentType string, ok bool) {
|
||||
if h.res != nil {
|
||||
return h.res.getContentType()
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
htmlRes struct {
|
||||
body []byte
|
||||
res Response
|
||||
}
|
||||
)
|
||||
|
||||
var _ Response = htmlRes{}
|
||||
|
||||
func HTML(body []byte) Response {
|
||||
return htmlRes{
|
||||
body: body,
|
||||
}
|
||||
}
|
||||
|
||||
func (h htmlRes) String() string {
|
||||
if h.res != nil {
|
||||
return fmt.Sprintf(`{"body": %q, "nested": %s}`, string(h.body), h.res)
|
||||
}
|
||||
return fmt.Sprintf(`{"body": %q}`, h.body)
|
||||
}
|
||||
|
||||
func (h htmlRes) wrap(res Response) Response {
|
||||
h.res = res
|
||||
return h
|
||||
}
|
||||
|
||||
func (h htmlRes) Status(code int) Response {
|
||||
return Status(code).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) Redirect(code redirect.Code, to string) Response {
|
||||
return Redirect(code, to).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HTML(body []byte) Response {
|
||||
h.body = body
|
||||
return h
|
||||
}
|
||||
|
||||
func (h htmlRes) JSON(body any) Response {
|
||||
return JSON(body).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) Body(body io.ReadCloser) Response {
|
||||
return Body(body).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) Cookie(ck http.Cookie) Response {
|
||||
return Cookie(ck).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXPushURL(v string) Response {
|
||||
return HXPushURL(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXLocation(v string) Response {
|
||||
return HXLocation(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXPushUrl(v string) Response {
|
||||
return HXPushUrl(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXRedirect(v string) Response {
|
||||
return HXRedirect(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXRefresh(v string) Response {
|
||||
return HXRefresh(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXReplaceUrl(v string) Response {
|
||||
return HXReplaceUrl(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXReswap(v string) Response {
|
||||
return HXReswap(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXRetarget(v string) Response {
|
||||
return HXRetarget(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXReselect(v string) Response {
|
||||
return HXReselect(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXTrigger(v string) Response {
|
||||
return HXTrigger(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXTriggerAfterSettle(v string) Response {
|
||||
return HXTriggerAfterSettle(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) HXTriggerAfterSwap(v string) Response {
|
||||
return HXTriggerAfterSwap(v).wrap(h)
|
||||
}
|
||||
|
||||
func (h htmlRes) GetStatus() (int, bool) {
|
||||
if h.res == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return h.res.GetStatus()
|
||||
}
|
||||
|
||||
func (h htmlRes) getHeaders() [][2]string {
|
||||
if h.res != nil {
|
||||
return h.res.getHeaders()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h htmlRes) GetRedirect() (code redirect.Code, to string, ok bool) {
|
||||
if h.res == nil {
|
||||
return 0, "", false
|
||||
}
|
||||
|
||||
return h.res.GetRedirect()
|
||||
}
|
||||
|
||||
func (h htmlRes) getBody() (body io.ReadCloser, ok bool, err error) {
|
||||
return io.NopCloser(bytes.NewBuffer(h.body)), true, nil
|
||||
}
|
||||
|
||||
func (h htmlRes) getCookies() []http.Cookie {
|
||||
if h.res != nil {
|
||||
return h.res.getCookies()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h htmlRes) getContentType() (contentType string, ok bool) {
|
||||
return "text/html", true
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
jsonRes struct {
|
||||
body any
|
||||
res Response
|
||||
}
|
||||
)
|
||||
|
||||
var _ Response = jsonRes{}
|
||||
|
||||
func JSON(body any) Response {
|
||||
return jsonRes{
|
||||
body: body,
|
||||
}
|
||||
}
|
||||
|
||||
func (j jsonRes) String() string {
|
||||
if j.res != nil {
|
||||
return fmt.Sprintf(`{"body": %q, "nested": %s}`, j.body, j.res)
|
||||
}
|
||||
return fmt.Sprintf(`{"body": %q}`, j.body)
|
||||
}
|
||||
|
||||
func (j jsonRes) wrap(res Response) Response {
|
||||
j.res = res
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonRes) Status(code int) Response {
|
||||
return Status(code).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) Redirect(code redirect.Code, to string) Response {
|
||||
return Redirect(code, to).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HTML(body []byte) Response {
|
||||
return HTML(body).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) JSON(body any) Response {
|
||||
j.body = body
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonRes) Body(body io.ReadCloser) Response {
|
||||
return Body(body).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) Cookie(ck http.Cookie) Response {
|
||||
return Cookie(ck).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXPushURL(v string) Response {
|
||||
return HXPushURL(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXLocation(v string) Response {
|
||||
return HXLocation(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXPushUrl(v string) Response {
|
||||
return HXPushUrl(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXRedirect(v string) Response {
|
||||
return HXRedirect(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXRefresh(v string) Response {
|
||||
return HXRefresh(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXReplaceUrl(v string) Response {
|
||||
return HXReplaceUrl(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXReswap(v string) Response {
|
||||
return HXReswap(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXRetarget(v string) Response {
|
||||
return HXRetarget(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXReselect(v string) Response {
|
||||
return HXReselect(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXTrigger(v string) Response {
|
||||
return HXTrigger(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXTriggerAfterSettle(v string) Response {
|
||||
return HXTriggerAfterSettle(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) HXTriggerAfterSwap(v string) Response {
|
||||
return HXTriggerAfterSwap(v).wrap(j)
|
||||
}
|
||||
|
||||
func (j jsonRes) GetStatus() (int, bool) {
|
||||
if j.res == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return j.res.GetStatus()
|
||||
}
|
||||
|
||||
func (j jsonRes) getHeaders() [][2]string {
|
||||
if j.res != nil {
|
||||
return j.res.getHeaders()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j jsonRes) GetRedirect() (code redirect.Code, to string, ok bool) {
|
||||
if j.res == nil {
|
||||
return 0, "", false
|
||||
}
|
||||
|
||||
return j.res.GetRedirect()
|
||||
}
|
||||
|
||||
func (j jsonRes) getBody() (body io.ReadCloser, ok bool, err error) {
|
||||
buf := new(bytes.Buffer)
|
||||
return io.NopCloser(buf), true, json.NewEncoder(buf).Encode(j.body)
|
||||
}
|
||||
|
||||
func (j jsonRes) getCookies() []http.Cookie {
|
||||
if j.res != nil {
|
||||
return j.res.getCookies()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j jsonRes) getContentType() (contentType string, ok bool) {
|
||||
return "application/json", true
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
redirectRes struct {
|
||||
code redirect.Code
|
||||
to string
|
||||
res Response
|
||||
}
|
||||
)
|
||||
|
||||
var _ Response = redirectRes{}
|
||||
|
||||
// convenience constructors
|
||||
|
||||
func MovedPermanently(to string) Response {
|
||||
return redirectRes{
|
||||
code: redirect.MovedPermanently,
|
||||
to: to,
|
||||
}
|
||||
}
|
||||
|
||||
func Found(to string) Response {
|
||||
return redirectRes{
|
||||
code: redirect.Found,
|
||||
to: to,
|
||||
}
|
||||
}
|
||||
|
||||
func SeeOther(to string) Response {
|
||||
return redirectRes{
|
||||
code: redirect.SeeOther,
|
||||
to: to,
|
||||
}
|
||||
}
|
||||
|
||||
func TemporaryRedirect(to string) Response {
|
||||
return redirectRes{
|
||||
code: redirect.TemporaryRedirect,
|
||||
to: to,
|
||||
}
|
||||
}
|
||||
|
||||
func PermanentRedirect(to string) Response {
|
||||
return redirectRes{
|
||||
code: redirect.PermanentRedirect,
|
||||
to: to,
|
||||
}
|
||||
}
|
||||
|
||||
func Redirect(code redirect.Code, to string) Response {
|
||||
return redirectRes{
|
||||
code: code,
|
||||
to: to,
|
||||
}
|
||||
}
|
||||
|
||||
func (r redirectRes) String() string {
|
||||
if r.res != nil {
|
||||
return fmt.Sprintf(`{"redirect": {"code": %d, "to": %q}, "nested": %s}`, r.code, r.to, r.res)
|
||||
}
|
||||
return fmt.Sprintf(`{"redirect": {"code": %d, "to": %q}}`, r.code, r.to)
|
||||
}
|
||||
|
||||
func (r redirectRes) wrap(res Response) Response {
|
||||
r.res = res
|
||||
return r
|
||||
}
|
||||
|
||||
func (r redirectRes) Status(code int) Response {
|
||||
return Status(code).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) Redirect(code redirect.Code, to string) Response {
|
||||
r.code = code
|
||||
r.to = to
|
||||
return r
|
||||
}
|
||||
|
||||
func (r redirectRes) HTML(body []byte) Response {
|
||||
return HTML(body).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) JSON(body any) Response {
|
||||
return JSON(body).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) Body(body io.ReadCloser) Response {
|
||||
return Body(body).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) Cookie(ck http.Cookie) Response {
|
||||
return Cookie(ck).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXPushURL(v string) Response {
|
||||
return HXPushURL(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXLocation(v string) Response {
|
||||
return HXLocation(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXPushUrl(v string) Response {
|
||||
return HXPushUrl(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXRedirect(v string) Response {
|
||||
return HXRedirect(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXRefresh(v string) Response {
|
||||
return HXRefresh(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXReplaceUrl(v string) Response {
|
||||
return HXReplaceUrl(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXReswap(v string) Response {
|
||||
return HXReswap(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXRetarget(v string) Response {
|
||||
return HXRetarget(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXReselect(v string) Response {
|
||||
return HXReselect(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXTrigger(v string) Response {
|
||||
return HXTrigger(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXTriggerAfterSettle(v string) Response {
|
||||
return HXTriggerAfterSettle(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) HXTriggerAfterSwap(v string) Response {
|
||||
return HXTriggerAfterSwap(v).wrap(r)
|
||||
}
|
||||
|
||||
func (r redirectRes) GetStatus() (int, bool) {
|
||||
if r.res == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return r.res.GetStatus()
|
||||
}
|
||||
|
||||
func (r redirectRes) getHeaders() [][2]string {
|
||||
if r.res != nil {
|
||||
return r.res.getHeaders()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r redirectRes) GetRedirect() (code redirect.Code, to string, ok bool) {
|
||||
return r.code, r.to, true
|
||||
}
|
||||
|
||||
func (r redirectRes) getBody() (body io.ReadCloser, ok bool, err error) {
|
||||
if r.res == nil {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
return r.res.getBody()
|
||||
}
|
||||
|
||||
func (r redirectRes) getCookies() []http.Cookie {
|
||||
if r.res != nil {
|
||||
return r.res.getCookies()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r redirectRes) getContentType() (contentType string, ok bool) {
|
||||
if r.res != nil {
|
||||
return r.res.getContentType()
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
Response interface {
|
||||
Status(int) Response
|
||||
HXPushURL(string) Response
|
||||
HXLocation(string) Response
|
||||
HXPushUrl(string) Response
|
||||
HXRedirect(string) Response
|
||||
HXRefresh(string) Response
|
||||
HXReplaceUrl(string) Response
|
||||
HXReswap(string) Response
|
||||
HXRetarget(string) Response
|
||||
HXReselect(string) Response
|
||||
HXTrigger(string) Response
|
||||
HXTriggerAfterSettle(string) Response
|
||||
HXTriggerAfterSwap(string) Response
|
||||
Redirect(code redirect.Code, to string) Response
|
||||
Body(io.ReadCloser) Response
|
||||
HTML([]byte) Response
|
||||
JSON(any) Response
|
||||
Cookie(http.Cookie) Response
|
||||
|
||||
GetStatus() (code int, ok bool)
|
||||
getBody() (body io.ReadCloser, ok bool, err error)
|
||||
GetRedirect() (code redirect.Code, to string, ok bool)
|
||||
getCookies() []http.Cookie
|
||||
getContentType() (contentType string, ok bool)
|
||||
getHeaders() [][2]string
|
||||
|
||||
wrap(Response) Response
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,168 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"ruben/inventory2/server/redirect"
|
||||
)
|
||||
|
||||
type (
|
||||
statusRes struct {
|
||||
code int
|
||||
res Response
|
||||
}
|
||||
)
|
||||
|
||||
var _ Response = statusRes{}
|
||||
|
||||
func Status(code int) Response {
|
||||
return statusRes{
|
||||
code: code,
|
||||
}
|
||||
}
|
||||
|
||||
func StatusOK() Response {
|
||||
return Status(http.StatusOK)
|
||||
}
|
||||
|
||||
func StatusCreated() Response {
|
||||
return Status(http.StatusCreated)
|
||||
}
|
||||
|
||||
func StatusAccepted() Response {
|
||||
return Status(http.StatusAccepted)
|
||||
}
|
||||
|
||||
func StatusNoContent() Response {
|
||||
return Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func (s statusRes) String() string {
|
||||
if s.res != nil {
|
||||
return fmt.Sprintf(`{"status": %d, "nested": %s}`, s.code, s.res)
|
||||
}
|
||||
return fmt.Sprintf(`{"status": %d}`, s.code)
|
||||
}
|
||||
|
||||
func (s statusRes) wrap(res Response) Response {
|
||||
s.res = res
|
||||
return s
|
||||
}
|
||||
|
||||
func (s statusRes) Status(code int) Response {
|
||||
s.code = code
|
||||
return s
|
||||
}
|
||||
|
||||
func (s statusRes) Redirect(code redirect.Code, to string) Response {
|
||||
return Redirect(code, to).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HTML(body []byte) Response {
|
||||
return HTML(body).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) JSON(body any) Response {
|
||||
return JSON(body).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) Body(body io.ReadCloser) Response {
|
||||
return Body(body).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) Cookie(ck http.Cookie) Response {
|
||||
return Cookie(ck).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXPushURL(v string) Response {
|
||||
return HXPushURL(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXLocation(v string) Response {
|
||||
return HXLocation(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXPushUrl(v string) Response {
|
||||
return HXPushUrl(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXRedirect(v string) Response {
|
||||
return HXRedirect(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXRefresh(v string) Response {
|
||||
return HXRefresh(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXReplaceUrl(v string) Response {
|
||||
return HXReplaceUrl(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXReswap(v string) Response {
|
||||
return HXReswap(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXRetarget(v string) Response {
|
||||
return HXRetarget(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXReselect(v string) Response {
|
||||
return HXReselect(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXTrigger(v string) Response {
|
||||
return HXTrigger(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXTriggerAfterSettle(v string) Response {
|
||||
return HXTriggerAfterSettle(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) HXTriggerAfterSwap(v string) Response {
|
||||
return HXTriggerAfterSwap(v).wrap(s)
|
||||
}
|
||||
|
||||
func (s statusRes) GetStatus() (int, bool) {
|
||||
return s.code, true
|
||||
}
|
||||
|
||||
func (s statusRes) getHeaders() [][2]string {
|
||||
if s.res != nil {
|
||||
return s.res.getHeaders()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s statusRes) GetRedirect() (code redirect.Code, to string, ok bool) {
|
||||
if s.res == nil {
|
||||
return 0, "", false
|
||||
}
|
||||
|
||||
return s.res.GetRedirect()
|
||||
}
|
||||
|
||||
func (s statusRes) getBody() (body io.ReadCloser, ok bool, err error) {
|
||||
if s.res == nil {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
return s.res.getBody()
|
||||
}
|
||||
|
||||
func (s statusRes) getCookies() []http.Cookie {
|
||||
if s.res != nil {
|
||||
return s.res.getCookies()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s statusRes) getContentType() (contentType string, ok bool) {
|
||||
if s.res != nil {
|
||||
return s.res.getContentType()
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"ruben/inventory2/consts"
|
||||
)
|
||||
|
||||
func HandleResponses(c *gin.Context) {
|
||||
c.Next()
|
||||
|
||||
if len(c.Errors) > 0 || c.Writer.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
v, ok := c.Get(responseKey{})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
res, ok := v.(Response)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
writeResponse(c, res)
|
||||
}
|
||||
|
||||
func HandleErrors(c *gin.Context) {
|
||||
c.Next()
|
||||
|
||||
if len(c.Errors) == 0 || c.Writer.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
err ErrorResponse
|
||||
ok bool
|
||||
)
|
||||
for _, e := range c.Errors {
|
||||
if err, ok = GetError(e); ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
var (
|
||||
err error
|
||||
status int
|
||||
statusFound bool
|
||||
)
|
||||
for _, e := range c.Errors {
|
||||
err = errors.Join(err, e)
|
||||
if !statusFound {
|
||||
status, statusFound = mapErrorConstantsToStatus(e)
|
||||
}
|
||||
}
|
||||
|
||||
if !statusFound {
|
||||
status = http.StatusInternalServerError
|
||||
}
|
||||
|
||||
c.String(status, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
status, ok := err.GetStatus()
|
||||
if !ok {
|
||||
status = http.StatusInternalServerError
|
||||
}
|
||||
if h, ok := err.GetHTML(); ok {
|
||||
c.Status(status)
|
||||
c.Header("Content-Type", "text/html")
|
||||
c.Writer.Write(h)
|
||||
return
|
||||
}
|
||||
|
||||
msg, ok := err.GetMsg()
|
||||
if !ok {
|
||||
msg = err.Error()
|
||||
}
|
||||
c.String(status, msg)
|
||||
}
|
||||
|
||||
func writeResponse(c *gin.Context, res Response) {
|
||||
w := c.Writer
|
||||
|
||||
// w.Header() must be set before ResponseWriter.WriteHeader is called
|
||||
// or redirect is attempted
|
||||
hdrs := w.Header()
|
||||
for _, hdr := range res.getHeaders() {
|
||||
hdrs.Add(hdr[0], hdr[1])
|
||||
}
|
||||
|
||||
for _, ck := range res.getCookies() {
|
||||
hdrs.Add("Set-Cookie", ck.String())
|
||||
}
|
||||
|
||||
if ct, ok := res.getContentType(); ok {
|
||||
hdrs.Set("Content-Type", ct)
|
||||
}
|
||||
|
||||
if code, to, ok := res.GetRedirect(); ok {
|
||||
c.Redirect(code.Int(), to)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
// the body is written after the status header, but it's read here
|
||||
// first, because if an error is incurred, an error status header will
|
||||
// need to be written.
|
||||
body, bodySet, err := res.getBody()
|
||||
if err != nil {
|
||||
http.Error(
|
||||
w,
|
||||
fmt.Sprintf("Failed to construct response body: %v", err.Error()),
|
||||
http.StatusInternalServerError,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if status, ok := res.GetStatus(); ok {
|
||||
w.WriteHeader(status)
|
||||
}
|
||||
if bodySet {
|
||||
// will automatically set the status header,
|
||||
// if w.WriteHeader wasn't already called
|
||||
io.Copy(w, body)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func GetStatusFromError(err error) int {
|
||||
status := http.StatusInternalServerError
|
||||
|
||||
if e, ok := GetError(err); ok {
|
||||
if status, ok = e.GetStatus(); !ok {
|
||||
status = http.StatusInternalServerError
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
func mapErrorConstantsToStatus(err error) (int, bool) {
|
||||
for {
|
||||
switch err {
|
||||
case consts.ErrBadRequest:
|
||||
return http.StatusBadRequest, true
|
||||
case consts.ErrNotFound:
|
||||
return http.StatusNotFound, true
|
||||
case consts.ErrConflict:
|
||||
return http.StatusConflict, true
|
||||
default:
|
||||
werr, ok := err.(interface {
|
||||
Unwrap() error
|
||||
})
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
err = werr.Unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user