aboutsummaryrefslogtreecommitdiff
path: root/utils/shortcuts/functions.go
diff options
context:
space:
mode:
Diffstat (limited to 'utils/shortcuts/functions.go')
-rw-r--r--utils/shortcuts/functions.go97
1 files changed, 97 insertions, 0 deletions
diff --git a/utils/shortcuts/functions.go b/utils/shortcuts/functions.go
new file mode 100644
index 0000000..df00dcf
--- /dev/null
+++ b/utils/shortcuts/functions.go
@@ -0,0 +1,97 @@
+package shortcuts
+
+import (
+ "maps"
+ "reflect"
+ "strings"
+
+ "dove/messages"
+ "dove/utils/errors"
+
+ "github.com/gofiber/fiber/v2"
+)
+
+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