aboutsummaryrefslogtreecommitdiff
path: root/utils/shortcuts
diff options
context:
space:
mode:
Diffstat (limited to 'utils/shortcuts')
-rw-r--r--utils/shortcuts/error.go51
-rw-r--r--utils/shortcuts/functions.go110
-rw-r--r--utils/shortcuts/messages.go5
-rw-r--r--utils/shortcuts/render.go108
4 files changed, 145 insertions, 129 deletions
diff --git a/utils/shortcuts/error.go b/utils/shortcuts/error.go
index 71fa4bd..c22e6b2 100644
--- a/utils/shortcuts/error.go
+++ b/utils/shortcuts/error.go
@@ -1,29 +1,44 @@
package shortcuts
-import (
- "dove/enums"
- "dove/types"
+import "github.com/gofiber/fiber/v2"
- "github.com/gofiber/fiber/v2"
+type ErrorKind string
+
+const (
+ BadRequest ErrorKind = "bad_request"
+ Forbidden ErrorKind = "forbidden"
+ Internal ErrorKind = "internal"
+ NotFound ErrorKind = "not_found"
+ Unauthorized ErrorKind = "unauthorized"
+ Unprocessable ErrorKind = "unprocessable"
)
-var statusMap = map[enums.ErrorKind]int{
- enums.BadRequest: fiber.StatusBadRequest,
- enums.Forbidden: fiber.StatusForbidden,
- enums.Internal: fiber.StatusInternalServerError,
- enums.NotFound: fiber.StatusNotFound,
- enums.Unauthorized: fiber.StatusUnauthorized,
- enums.Unprocessable: fiber.StatusUnprocessableEntity,
+type Error struct {
+ Kind ErrorKind
+ Message string
+}
+
+func (self *Error) Error() string {
+ return self.Message
+}
+
+var statusMap = map[ErrorKind]int{
+ BadRequest: fiber.StatusBadRequest,
+ Forbidden: fiber.StatusForbidden,
+ Internal: fiber.StatusInternalServerError,
+ NotFound: fiber.StatusNotFound,
+ Unauthorized: fiber.StatusUnauthorized,
+ Unprocessable: fiber.StatusUnprocessableEntity,
}
-func ServiceError(kind enums.ErrorKind, message string) *types.ServiceError {
- return &types.ServiceError{
+func ServiceError(kind ErrorKind, message string) *Error {
+ return &Error{
Kind: kind,
Message: message,
}
}
-func HandleError(context *fiber.Ctx, serviceError *types.ServiceError) error {
+func HandleError(context *fiber.Ctx, serviceError *Error) error {
statusCode, exists := statusMap[serviceError.Kind]
if !exists {
statusCode = fiber.StatusInternalServerError
@@ -34,13 +49,13 @@ func HandleError(context *fiber.Ctx, serviceError *types.ServiceError) error {
}, statusCode)
}
-func BadRequest(context *fiber.Ctx, err error) error {
+func BadRequestError(context *fiber.Ctx, err error) error {
return RenderWithStatus(context, "error", fiber.Map{
"ErrorMessage": err.Error(),
}, fiber.StatusBadRequest)
}
-func Forbidden(context *fiber.Ctx, err error) error {
+func ForbiddenError(context *fiber.Ctx, err error) error {
return RenderWithStatus(context, "error", fiber.Map{
"ErrorMessage": err.Error(),
}, fiber.StatusForbidden)
@@ -52,13 +67,13 @@ func InternalServerError(context *fiber.Ctx, err error) error {
}, fiber.StatusInternalServerError)
}
-func NotFound(context *fiber.Ctx, err error) error {
+func NotFoundError(context *fiber.Ctx, err error) error {
return RenderWithStatus(context, "error", fiber.Map{
"ErrorMessage": err.Error(),
}, fiber.StatusNotFound)
}
-func Unauthorized(context *fiber.Ctx, err error) error {
+func UnauthorizedError(context *fiber.Ctx, err error) error {
return RenderWithStatus(context, "error", fiber.Map{
"ErrorMessage": err.Error(),
}, fiber.StatusUnauthorized)
diff --git a/utils/shortcuts/functions.go b/utils/shortcuts/functions.go
deleted file mode 100644
index 3e76a9a..0000000
--- a/utils/shortcuts/functions.go
+++ /dev/null
@@ -1,110 +0,0 @@
-package shortcuts
-
-import (
- "fmt"
- "maps"
- "path"
- "reflect"
- "strings"
-
- "dove/messages"
- "dove/utils/errors"
-
- "github.com/gofiber/fiber/v2"
-)
-
-func resolveTemplate(context *fiber.Ctx, templateName string) string {
- switch {
- case context.Get("HX-Request") == "true" && context.Get("HX-Boosted") != "true":
- directory := path.Dir(templateName)
- filename := path.Base(templateName)
- return fmt.Sprintf("%s/htmx/%s.htmx", directory, filename)
- default:
- return templateName
- }
-}
-
-func mergeContextValues(context *fiber.Ctx, targetMap fiber.Map) {
- context.Context().VisitUserValues(func(key []byte, value any) {
- targetMap[string(key)] = value
- })
-}
-
-func mergeBindData(targetMap fiber.Map, data any) error {
- normalizedData, normalizeError := normalizeToMap(data)
- if normalizeError != nil {
- return normalizeError
- }
-
- maps.Copy(targetMap, normalizedData)
- return nil
-}
-
-func normalizeToMap(data any) (fiber.Map, error) {
- switch typedData := data.(type) {
- case fiber.Map:
- return typedData, nil
- case map[string]any:
- return fiber.Map(typedData), nil
- default:
- return convertStructToMap(data)
- }
-}
-
-func convertStructToMap(data any) (fiber.Map, error) {
- structValue := reflect.ValueOf(data)
-
- switch structValue.Kind() {
- case reflect.Pointer:
- structValue = structValue.Elem()
- }
-
- switch structValue.Kind() {
- case reflect.Struct:
- return extractStructFields(structValue), nil
- default:
- return nil, errors.Error(messages.ShortcutUnsupportedBindType)
- }
-}
-
-func extractStructFields(structValue reflect.Value) fiber.Map {
- structType := structValue.Type()
- fieldMap := make(fiber.Map, structValue.NumField())
-
- for fieldIndex := range structType.NumField() {
- fieldDescriptor := structType.Field(fieldIndex)
-
- if !fieldDescriptor.IsExported() {
- continue
- }
-
- fieldKey := resolveFieldKey(fieldDescriptor)
- fieldMap[fieldKey] = structValue.Field(fieldIndex).Interface()
- }
-
- return fieldMap
-}
-
-func resolveFieldKey(fieldDescriptor reflect.StructField) string {
- jsonTag := fieldDescriptor.Tag.Get("json")
-
- switch {
- case jsonTag == "" || jsonTag == "-":
- return fieldDescriptor.Name
- default:
- return extractTagName(jsonTag, fieldDescriptor.Name)
- }
-}
-
-func extractTagName(jsonTag string, fallbackName string) string {
- separatorIndex := strings.IndexByte(jsonTag, ',')
-
- switch {
- case separatorIndex < 0:
- return jsonTag
- case separatorIndex > 0:
- return jsonTag[:separatorIndex]
- default:
- return fallbackName
- }
-} \ No newline at end of file
diff --git a/utils/shortcuts/messages.go b/utils/shortcuts/messages.go
new file mode 100644
index 0000000..92df139
--- /dev/null
+++ b/utils/shortcuts/messages.go
@@ -0,0 +1,5 @@
+package shortcuts
+
+const (
+ UnsupportedBindType = "Bind data must be a struct, *struct, fiber.Map, or map[string]any."
+)
diff --git a/utils/shortcuts/render.go b/utils/shortcuts/render.go
index e91ccfa..89779cf 100644
--- a/utils/shortcuts/render.go
+++ b/utils/shortcuts/render.go
@@ -1,6 +1,16 @@
package shortcuts
-import "github.com/gofiber/fiber/v2"
+import (
+ "fmt"
+ "maps"
+ "path"
+ "reflect"
+ "strings"
+
+ "dove/utils/errors"
+
+ "github.com/gofiber/fiber/v2"
+)
func Render(context *fiber.Ctx, templateName string, data any) error {
templateData := make(fiber.Map)
@@ -20,3 +30,99 @@ func RenderWithStatus(context *fiber.Ctx, templateName string, data any, statusC
context.Status(statusCode)
return Render(context, templateName, data)
}
+
+func resolveTemplate(context *fiber.Ctx, templateName string) string {
+ switch {
+ case context.Get("HX-Request") == "true" && context.Get("HX-Boosted") != "true":
+ directory := path.Dir(templateName)
+ filename := path.Base(templateName)
+ return fmt.Sprintf("%s/htmx/%s.htmx", directory, filename)
+ default:
+ return templateName
+ }
+}
+
+func mergeContextValues(context *fiber.Ctx, targetMap fiber.Map) {
+ context.Context().VisitUserValues(func(key []byte, value any) {
+ targetMap[string(key)] = value
+ })
+}
+
+func mergeBindData(targetMap fiber.Map, data any) error {
+ normalizedData, normalizeError := normalizeToMap(data)
+ if normalizeError != nil {
+ return normalizeError
+ }
+
+ maps.Copy(targetMap, normalizedData)
+ return nil
+}
+
+func normalizeToMap(data any) (fiber.Map, error) {
+ switch typedData := data.(type) {
+ case fiber.Map:
+ return typedData, nil
+ case map[string]any:
+ return fiber.Map(typedData), nil
+ default:
+ return convertStructToMap(data)
+ }
+}
+
+func convertStructToMap(data any) (fiber.Map, error) {
+ structValue := reflect.ValueOf(data)
+
+ switch structValue.Kind() {
+ case reflect.Pointer:
+ structValue = structValue.Elem()
+ }
+
+ switch structValue.Kind() {
+ case reflect.Struct:
+ return extractStructFields(structValue), nil
+ default:
+ return nil, errors.Error(UnsupportedBindType)
+ }
+}
+
+func extractStructFields(structValue reflect.Value) fiber.Map {
+ structType := structValue.Type()
+ fieldMap := make(fiber.Map, structValue.NumField())
+
+ for fieldIndex := range structType.NumField() {
+ fieldDescriptor := structType.Field(fieldIndex)
+
+ if !fieldDescriptor.IsExported() {
+ continue
+ }
+
+ fieldKey := resolveFieldKey(fieldDescriptor)
+ fieldMap[fieldKey] = structValue.Field(fieldIndex).Interface()
+ }
+
+ return fieldMap
+}
+
+func resolveFieldKey(fieldDescriptor reflect.StructField) string {
+ jsonTag := fieldDescriptor.Tag.Get("json")
+
+ switch {
+ case jsonTag == "" || jsonTag == "-":
+ return fieldDescriptor.Name
+ default:
+ return extractTagName(jsonTag, fieldDescriptor.Name)
+ }
+}
+
+func extractTagName(jsonTag string, fallbackName string) string {
+ separatorIndex := strings.IndexByte(jsonTag, ',')
+
+ switch {
+ case separatorIndex < 0:
+ return jsonTag
+ case separatorIndex > 0:
+ return jsonTag[:separatorIndex]
+ default:
+ return fallbackName
+ }
+}