diff options
| author | Bobby <[email protected]> | 2026-01-20 14:26:45 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-01-20 14:26:45 +0530 |
| commit | 374fa73e53a3e8613f4b68e8d016c74d557d79a1 (patch) | |
| tree | 7122c52661ea3bee2137e8f87079e776d093ee25 /utils | |
| parent | 2a513445a50bbe0d3a5cb13784c8ed68e1c367fa (diff) | |
| download | cafe-374fa73e53a3e8613f4b68e8d016c74d557d79a1.tar.xz cafe-374fa73e53a3e8613f4b68e8d016c74d557d79a1.zip | |
Add shortcuts utility functions for rendering and error handling
Diffstat (limited to 'utils')
| -rw-r--r-- | utils/shortcuts/error.go | 25 | ||||
| -rw-r--r-- | utils/shortcuts/flash.go | 31 | ||||
| -rw-r--r-- | utils/shortcuts/helpers.go | 111 | ||||
| -rw-r--r-- | utils/shortcuts/redirect.go | 36 | ||||
| -rw-r--r-- | utils/shortcuts/render.go | 28 |
5 files changed, 231 insertions, 0 deletions
diff --git a/utils/shortcuts/error.go b/utils/shortcuts/error.go new file mode 100644 index 0000000..efbf2c1 --- /dev/null +++ b/utils/shortcuts/error.go @@ -0,0 +1,25 @@ +package shortcuts + +import ( + "cafe/types" + "cafe/utils/meta" + "errors" + + "github.com/gofiber/fiber/v2" +) + +func BuildErrorMessage(err error, alternateString string) error { + if err != nil { + return err + } + + return errors.New(alternateString) +} + +func RenderError(error types.TemplateError) error { + meta.SetPageTitle(error.Context, error.PageTitle) + return RenderWithStatus(error.Context, "error", fiber.Map{ + "ErrorTitle": error.PageTitle, + "ErrorMessage": error.ErrorMessage.Error(), + }, error.StatusCode) +} diff --git a/utils/shortcuts/flash.go b/utils/shortcuts/flash.go new file mode 100644 index 0000000..ffb0afc --- /dev/null +++ b/utils/shortcuts/flash.go @@ -0,0 +1,31 @@ +package shortcuts + +import ( + "cafe/session" + + "github.com/gofiber/fiber/v2" +) + +const flashKey = "__flash__" + +func flash(ctx *fiber.Ctx, data any) error { + normalized, err := normalizeBind(data) + if err != nil { + return err + } + + return session.Set(ctx, flashKey, normalized) +} + +func consumeFlash(ctx *fiber.Ctx) (any, error) { + value, err := session.Get(ctx, flashKey) + if err != nil || value == nil { + return nil, err + } + + if err := session.Delete(ctx, flashKey); err != nil { + return nil, err + } + + return value, nil +} diff --git a/utils/shortcuts/helpers.go b/utils/shortcuts/helpers.go new file mode 100644 index 0000000..7fee04e --- /dev/null +++ b/utils/shortcuts/helpers.go @@ -0,0 +1,111 @@ +package shortcuts + +import ( + "fmt" + "maps" + "reflect" + "strings" + + "github.com/gofiber/fiber/v2" +) + +func structValue(data any) (reflect.Value, error) { + v := reflect.ValueOf(data) + if v.Kind() == reflect.Pointer { + v = v.Elem() + } + + if v.Kind() != reflect.Struct { + return reflect.Value{}, fmt.Errorf("unsupported bind type %T; must be struct or *struct", data) + } + + return v, nil +} + +func mapStruct(v reflect.Value) map[string]any { + t := v.Type() + result := make(map[string]any, v.NumField()) + + for i := 0; i < v.NumField(); i++ { + field := t.Field(i) + if !field.IsExported() { + continue + } + + result[getFieldKey(field)] = v.Field(i).Interface() + } + + return result +} + +func getFieldKey(field reflect.StructField) string { + key := field.Name + tag := field.Tag.Get("json") + + if tag == "" || tag == "-" { + return key + } + + if idx := strings.IndexByte(tag, ','); idx >= 0 { + if idx > 0 { + return tag[:idx] + } + return key + } + + return tag +} + +func normalizeBind(data any) (fiber.Map, error) { + if data == nil { + return nil, nil + } + + switch v := data.(type) { + case fiber.Map: + return v, nil + case map[string]any: + return fiber.Map(v), nil + default: + return structToMap(v) + } +} + +func structToMap(data any) (fiber.Map, error) { + v, err := structValue(data) + if err != nil { + return nil, err + } + return fiber.Map(mapStruct(v)), nil +} + +func mergeFlash(ctx *fiber.Ctx, bind fiber.Map) error { + flash, err := consumeFlash(ctx) + if err != nil || flash == nil { + return err + } + + flashMap, err := normalizeBind(flash) + if err != nil { + return err + } + + maps.Copy(bind, flashMap) + return nil +} + +func mergeUserValues(ctx *fiber.Ctx, bind fiber.Map) { + ctx.Context().VisitUserValues(func(key []byte, value any) { + bind[string(key)] = value + }) +} + +func mergeData(bind fiber.Map, data any) error { + dataMap, err := normalizeBind(data) + if err != nil { + return err + } + + maps.Copy(bind, dataMap) + return nil +} diff --git a/utils/shortcuts/redirect.go b/utils/shortcuts/redirect.go new file mode 100644 index 0000000..9c75679 --- /dev/null +++ b/utils/shortcuts/redirect.go @@ -0,0 +1,36 @@ +package shortcuts + +import ( + "cafe/utils/urls" + + "github.com/gofiber/fiber/v2" +) + +func Redirect(ctx *fiber.Ctx, routeName string) error { + path, ok := urls.GetFullPath(routeName) + if !ok { + return fiber.ErrNotFound + } + return ctx.Redirect(path) +} + +func RedirectWithStatus(ctx *fiber.Ctx, routeName string, statusCode int) error { + path, ok := urls.GetFullPath(routeName) + if !ok { + return fiber.ErrNotFound + } + return ctx.Redirect(path, statusCode) +} + +func RedirectTo(route string) fiber.Handler { + return func(ctx *fiber.Ctx) error { + return Redirect(ctx, route) + } +} + +func RedirectWithFlash(context *fiber.Ctx, routeName string, data fiber.Map) error { + if err := flash(context, data); err != nil { + return err + } + return Redirect(context, routeName) +} diff --git a/utils/shortcuts/render.go b/utils/shortcuts/render.go new file mode 100644 index 0000000..7862b91 --- /dev/null +++ b/utils/shortcuts/render.go @@ -0,0 +1,28 @@ +package shortcuts + +import ( + "github.com/gofiber/fiber/v2" +) + +func Render(ctx *fiber.Ctx, template string, data any) error { + bind := make(fiber.Map) + + if err := mergeFlash(ctx, bind); err != nil { + return err + } + + mergeUserValues(ctx, bind) + + if data != nil { + if err := mergeData(bind, data); err != nil { + return err + } + } + + return ctx.Render(template, bind) +} + +func RenderWithStatus(ctx *fiber.Ctx, template string, data any, statusCode int) error { + ctx.Status(statusCode) + return Render(ctx, template, data) +} |
