aboutsummaryrefslogtreecommitdiff
path: root/utils/shortcuts/render.go
blob: 19635e20ec50e4d71eda3c6f0c826d9cf7a26345 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package shortcuts

import (
	"reflect"
	"strings"

	"maps"

	"github.com/gofiber/fiber/v2"
)

func Render(ctx *fiber.Ctx, name string, bind any) error {
	finalData := fiber.Map{}

	ctx.Context().VisitUserValues(func(key []byte, value any) {
		finalData[string(key)] = value
	})

	if bind != nil {
		switch v := bind.(type) {
		case fiber.Map:
			maps.Copy(finalData, v)
		case map[string]any:
			maps.Copy(finalData, v)
		default:
			structData := structToMap(bind)
			maps.Copy(finalData, structData)
		}
	}

	return ctx.Render(name, finalData)
}

func RenderWithStatus(ctx *fiber.Ctx, name string, bind any, statusCode int) error {
	ctx.Status(statusCode)
	return Render(ctx, name, bind)
}

func structToMap(obj any) map[string]any {
	result := make(map[string]any)

	v := reflect.ValueOf(obj)
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	if v.Kind() != reflect.Struct {
		return result
	}

	t := v.Type()
	for i := range v.NumField() {
		field := t.Field(i)
		if !field.IsExported() {
			continue
		}

		key := field.Name
		if tag := field.Tag.Get("json"); tag != "" && tag != "-" {
			if commaIdx := strings.Index(tag, ","); commaIdx > 0 {
				key = tag[:commaIdx]
			} else if commaIdx == -1 {
				key = tag
			}
		}

		result[key] = v.Field(i).Interface()
	}

	return result
}