summaryrefslogtreecommitdiff
path: root/nexus/utils/shortcuts/render.go
diff options
context:
space:
mode:
Diffstat (limited to 'nexus/utils/shortcuts/render.go')
-rw-r--r--nexus/utils/shortcuts/render.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/nexus/utils/shortcuts/render.go b/nexus/utils/shortcuts/render.go
new file mode 100644
index 0000000..5f3678f
--- /dev/null
+++ b/nexus/utils/shortcuts/render.go
@@ -0,0 +1,103 @@
+package shortcuts
+
+import (
+ "maps"
+ "nexus/utils/collections"
+ "reflect"
+ "strings"
+
+ "github.com/gofiber/fiber/v2"
+)
+
+func Render(context *fiber.Ctx, templateName string, data any) error {
+ templateData := make(collections.Record[string, any])
+
+ if flash := ConsumeFlash(context); flash != nil {
+ maps.Copy(templateData, flash)
+ }
+
+ mergeContextValues(context, templateData)
+
+ if data != nil {
+ if mergeError := mergeBindData(templateData, data); mergeError != nil {
+ return mergeError
+ }
+ }
+
+ return context.Render(templateName, templateData)
+}
+
+func RenderWithStatus(context *fiber.Ctx, templateName string, data any, statusCode int) error {
+ context.Status(statusCode)
+ return Render(context, templateName, data)
+}
+
+func NoContent(context *fiber.Ctx) error {
+ return context.SendStatus(fiber.StatusNoContent)
+}
+
+func mergeContextValues(context *fiber.Ctx, target collections.Record[string, any]) {
+ context.Context().VisitUserValuesAll(func(key any, value any) {
+ switch typedKey := key.(type) {
+ case string:
+ if typedKey != "" {
+ target[typedKey] = value
+ }
+ case []byte:
+ if len(typedKey) > 0 {
+ target[string(typedKey)] = value
+ }
+ }
+ })
+}
+
+func mergeBindData(target collections.Record[string, any], data any) error {
+ normalized, err := normalizeToMap(data)
+ if err != nil {
+ return err
+ }
+ maps.Copy(target, normalized)
+ return nil
+}
+
+func normalizeToMap(data any) (collections.Record[string, any], error) {
+ switch v := data.(type) {
+ case collections.Record[string, any]:
+ return v, nil
+ default:
+ return convertStructToMap(data)
+ }
+}
+
+func convertStructToMap(data any) (collections.Record[string, any], error) {
+ v := reflect.ValueOf(data)
+ if v.Kind() == reflect.Pointer {
+ v = v.Elem()
+ }
+ if v.Kind() != reflect.Struct {
+ return nil, fiber.NewError(fiber.StatusInternalServerError, UnsupportedBindType)
+ }
+
+ t := v.Type()
+ result := make(collections.Record[string, any], t.NumField())
+
+ for i := range t.NumField() {
+ field := t.Field(i)
+ if !field.IsExported() {
+ continue
+ }
+
+ key := field.Name
+ if tag := field.Tag.Get("json"); tag != "" && tag != "-" {
+ if idx := strings.IndexByte(tag, ','); idx > 0 {
+ key = tag[:idx]
+ } else if idx < 0 {
+ key = tag
+ }
+ }
+
+ result[key] = v.Field(i).Interface()
+ }
+
+ return result, nil
+}