diff options
| author | Bobby <[email protected]> | 2026-03-08 02:27:15 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-03-08 02:27:15 +0530 |
| commit | cca905d35412f1549400fc3d1aca6dc704d8cae6 (patch) | |
| tree | 0c0231f5c2ebaeb7700e08a2c1f07373d3251658 /utils | |
| parent | 547384c41181c034a5eaf340c5e569d36eb013be (diff) | |
| download | dove-cca905d35412f1549400fc3d1aca6dc704d8cae6.tar.xz dove-cca905d35412f1549400fc3d1aca6dc704d8cae6.zip | |
feat(domains): add new TLD creation page and update sidebar
- Introduced a new HTMX template for creating TLDs.
- Created a new Django template for the new TLD page.
- Updated the sidebar to include a link to the domains section.
refactor(types): remove unused types and consolidate request handling
- Deleted unused type definitions related to authentication, errors, mailboxes, overview, requests, responses, and users.
- Introduced a new collections package for generic data structures.
- Refactored request handling to use a more streamlined approach with RequestInfo and Param types.
fix(meta): improve pagination and sorting functionality
- Updated pagination logic to handle default values and edge cases.
- Introduced a new Sorting type for better sorting management in queries.
chore(urls): refactor URL handling and registry
- Replaced enums with string constants for HTTP methods.
- Consolidated route registration logic and improved type safety with RegisteredRoute.
style(shortcuts): clean up error handling and rendering functions
- Enhanced error handling functions for better readability and maintainability.
- Removed deprecated functions and improved the structure of rendering logic.
Diffstat (limited to 'utils')
| -rw-r--r-- | utils/collections/record.go | 3 | ||||
| -rw-r--r-- | utils/collections/set.go | 38 | ||||
| -rw-r--r-- | utils/collections/types.go | 3 | ||||
| -rw-r--r-- | utils/meta/builder.go | 46 | ||||
| -rw-r--r-- | utils/meta/constants.go | 9 | ||||
| -rw-r--r-- | utils/meta/defaults.go | 9 | ||||
| -rw-r--r-- | utils/meta/functions.go | 53 | ||||
| -rw-r--r-- | utils/meta/messages.go | 5 | ||||
| -rw-r--r-- | utils/meta/pagination.go | 71 | ||||
| -rw-r--r-- | utils/meta/request.go | 78 | ||||
| -rw-r--r-- | utils/meta/sorting.go | 39 | ||||
| -rw-r--r-- | utils/meta/types.go | 26 | ||||
| -rw-r--r-- | utils/meta/value.go | 35 | ||||
| -rw-r--r-- | utils/shortcuts/error.go | 51 | ||||
| -rw-r--r-- | utils/shortcuts/functions.go | 110 | ||||
| -rw-r--r-- | utils/shortcuts/messages.go | 5 | ||||
| -rw-r--r-- | utils/shortcuts/render.go | 108 | ||||
| -rw-r--r-- | utils/toml/load.go | 4 | ||||
| -rw-r--r-- | utils/urls/attach.go | 22 | ||||
| -rw-r--r-- | utils/urls/functions.go | 30 | ||||
| -rw-r--r-- | utils/urls/path.go | 45 | ||||
| -rw-r--r-- | utils/urls/registry.go | 27 | ||||
| -rw-r--r-- | utils/urls/types.go | 25 |
23 files changed, 425 insertions, 417 deletions
diff --git a/utils/collections/record.go b/utils/collections/record.go new file mode 100644 index 0000000..a204436 --- /dev/null +++ b/utils/collections/record.go @@ -0,0 +1,3 @@ +package collections + +type Record[K comparable, V any] map[K]V diff --git a/utils/collections/set.go b/utils/collections/set.go new file mode 100644 index 0000000..79e1ae2 --- /dev/null +++ b/utils/collections/set.go @@ -0,0 +1,38 @@ +package collections + +type Set[T comparable] struct { + items []T + index map[T]bool +} + +func SetOf[T comparable](items ...T) Set[T] { + index := make(map[T]bool, len(items)) + uniqueItems := make([]T, 0, len(items)) + + for _, item := range items { + if index[item] { + continue + } + index[item] = true + uniqueItems = append(uniqueItems, item) + } + + return Set[T]{ + items: uniqueItems, + index: index, + } +} + +func (set Set[T]) Contains(item T) bool { + return set.index[item] +} + +func (set Set[T]) All() []T { + copied := make([]T, len(set.items)) + copy(copied, set.items) + return copied +} + +func (set Set[T]) Len() int { + return len(set.items) +} diff --git a/utils/collections/types.go b/utils/collections/types.go deleted file mode 100644 index ac84e76..0000000 --- a/utils/collections/types.go +++ /dev/null @@ -1,3 +0,0 @@ -package collections - -type Record[T any] map[string]T diff --git a/utils/meta/builder.go b/utils/meta/builder.go index 4ae2648..3e4de93 100644 --- a/utils/meta/builder.go +++ b/utils/meta/builder.go @@ -1,13 +1,9 @@ package meta -import ( - "dove/types" +import "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2" -) - -func BuildRequest(context *fiber.Ctx) types.Request { - return types.Request{ +func BuildRequest(context *fiber.Ctx) RequestInfo { + return RequestInfo{ Path: context.Path(), Method: context.Method(), Query: buildQueryParams(context), @@ -18,3 +14,39 @@ func BuildRequest(context *fiber.Ctx) types.Request { URL: context.OriginalURL(), } } + +func buildQueryParams(context *fiber.Ctx) []Param { + params := make([]Param, 0) + context.Request().URI().QueryArgs().VisitAll(func(name []byte, paramValue []byte) { + params = append(params, Param{ + Key: string(name), + Value: string(paramValue), + }) + }) + + return params +} + +func buildRouteParams(context *fiber.Ctx) []Param { + params := make([]Param, 0) + for name, routeValue := range context.AllParams() { + params = append(params, Param{ + Key: name, + Value: routeValue, + }) + } + + return params +} + +func buildHeaders(context *fiber.Ctx) []Param { + params := make([]Param, 0) + context.Request().Header.VisitAll(func(name []byte, headerValue []byte) { + params = append(params, Param{ + Key: string(name), + Value: string(headerValue), + }) + }) + + return params +} diff --git a/utils/meta/constants.go b/utils/meta/constants.go deleted file mode 100644 index 13a2fde..0000000 --- a/utils/meta/constants.go +++ /dev/null @@ -1,9 +0,0 @@ -package meta - -const ( - DEFAULT_PAGE = 1 - DEFAULT_PER_PAGE = 20 - LOG_PREFIX = "Meta" - MAX_PER_PAGE = 50 - REQUEST_KEY = "Request" -) diff --git a/utils/meta/defaults.go b/utils/meta/defaults.go new file mode 100644 index 0000000..9ba6dfe --- /dev/null +++ b/utils/meta/defaults.go @@ -0,0 +1,9 @@ +package meta + +const ( + DefaultPage = 1 + DefaultPerPage = 20 + LogPrefix = "Meta" + MaxPerPage = 50 + RequestKey = "Request" +) diff --git a/utils/meta/functions.go b/utils/meta/functions.go deleted file mode 100644 index 0b8f309..0000000 --- a/utils/meta/functions.go +++ /dev/null @@ -1,53 +0,0 @@ -package meta - -import ( - "dove/types" - - "github.com/gofiber/fiber/v2" -) - -func findParam(params []types.Param, key string) (string, bool) { - for _, param := range params { - if param.Key == key { - return param.Value, true - } - } - - return "", false -} - -func buildQueryParams(context *fiber.Ctx) []types.Param { - params := make([]types.Param, 0) - context.Request().URI().QueryArgs().VisitAll(func(name []byte, paramValue []byte) { - params = append(params, types.Param{ - Key: string(name), - Value: string(paramValue), - }) - }) - - return params -} - -func buildRouteParams(context *fiber.Ctx) []types.Param { - params := make([]types.Param, 0) - for name, routeValue := range context.AllParams() { - params = append(params, types.Param{ - Key: name, - Value: routeValue, - }) - } - - return params -} - -func buildHeaders(context *fiber.Ctx) []types.Param { - params := make([]types.Param, 0) - context.Request().Header.VisitAll(func(name []byte, headerValue []byte) { - params = append(params, types.Param{ - Key: string(name), - Value: string(headerValue), - }) - }) - - return params -} diff --git a/utils/meta/messages.go b/utils/meta/messages.go new file mode 100644 index 0000000..2814d7c --- /dev/null +++ b/utils/meta/messages.go @@ -0,0 +1,5 @@ +package meta + +const ( + RequestContextMissing = "Request context missing in fiber locals." +) diff --git a/utils/meta/pagination.go b/utils/meta/pagination.go index 9244294..d0dda08 100644 --- a/utils/meta/pagination.go +++ b/utils/meta/pagination.go @@ -1,80 +1,59 @@ package meta import ( - "dove/types" "strconv" "github.com/gofiber/fiber/v2" "gorm.io/gorm" ) -func Paginate(context *fiber.Ctx) Pagination { - requestData := Request(context) - - page := DEFAULT_PAGE - perPage := DEFAULT_PER_PAGE - - if requestData != nil { - if pageValue := requestData.Query("page"); pageValue != nil { - parsed, _ := strconv.Atoi(pageValue.String()) - if parsed >= DEFAULT_PAGE { - page = parsed - } - } - - if perPageValue := requestData.Query("per_page"); perPageValue != nil { - parsed, _ := strconv.Atoi(perPageValue.String()) - if parsed >= DEFAULT_PAGE && parsed <= MAX_PER_PAGE { - perPage = parsed - } - } - } +type Pagination struct { + Page int + PerPage int +} - return Pagination{Page: page, PerPage: perPage} +type PaginatedResponse struct { + Items any `json:"items"` + Total int64 `json:"total"` + Page int `json:"page"` + PerPage int `json:"per_page"` + TotalPages int `json:"total_pages"` } -func Sort(context *fiber.Ctx, allowedFields []string, fallbackField string) Sorting { +func Paginate(context *fiber.Ctx) Pagination { requestData := Request(context) - field := fallbackField - direction := "desc" + page := DefaultPage + perPage := DefaultPerPage - if requestData != nil { - if sortValue := requestData.Query("sort"); sortValue != nil { - for _, allowedField := range allowedFields { - if sortValue.String() == allowedField { - field = sortValue.String() - break - } - } + if pageValue := requestData.Query("page"); pageValue != "" { + parsed, _ := strconv.Atoi(pageValue) + if parsed >= DefaultPage { + page = parsed } + } - if orderValue := requestData.Query("order"); orderValue != nil { - switch orderValue.String() { - case "asc", "desc": - direction = orderValue.String() - } + if perPageValue := requestData.Query("per_page"); perPageValue != "" { + parsed, _ := strconv.Atoi(perPageValue) + if parsed >= DefaultPage && parsed <= MaxPerPage { + perPage = parsed } } - return Sorting{Field: field, Direction: direction} + return Pagination{Page: page, PerPage: perPage} } func (self Pagination) Apply(query *gorm.DB) *gorm.DB { return query.Offset((self.Page - 1) * self.PerPage).Limit(self.PerPage) } -func (self Sorting) Apply(query *gorm.DB) *gorm.DB { - return query.Order(self.Field + " " + self.Direction) -} - -func (self Pagination) Response(items any, total int64) types.PaginatedResponse { +func (self Pagination) Response(items any, total int64) PaginatedResponse { totalPages := int(total) / self.PerPage if int(total)%self.PerPage > 0 { totalPages++ } - return types.PaginatedResponse{ + return PaginatedResponse{ Items: items, Total: total, Page: self.Page, diff --git a/utils/meta/request.go b/utils/meta/request.go index 34a659a..e9a3720 100644 --- a/utils/meta/request.go +++ b/utils/meta/request.go @@ -1,63 +1,75 @@ package meta import ( - "dove/messages" - "dove/types" "dove/utils/logger" "github.com/gofiber/fiber/v2" ) -func Request(context *fiber.Ctx) *request { - data, ok := context.Locals(REQUEST_KEY).(types.Request) +type Param struct { + Key string + Value string +} + +type RequestInfo struct { + Path string + Method string + Query []Param + Params []Param + Headers []Param + QueryString string + IP string + URL string +} + +type RequestData struct { + RequestInfo + Context *fiber.Ctx +} + +func Request(context *fiber.Ctx) *RequestData { + data, ok := context.Locals(RequestKey).(RequestInfo) if !ok { - logger.Errorf(LOG_PREFIX, messages.MetaRequestContextMissing) + logger.Errorf(LogPrefix, RequestContextMissing) return nil } - return &request{ - Request: data, - context: context, + return &RequestData{ + RequestInfo: data, + Context: context, } } -func (self *request) Param(key string) *value { - if self == nil { - return nil - } - - if self.context != nil { - result := self.context.Params(key) - if result != "" { - return &value{data: result} - } +func (self *RequestData) Param(key string) string { + if self == nil || self.Context == nil { + return "" } - return nil + return self.Context.Params(key) } -func (self *request) Query(key string) *value { +func (self *RequestData) Query(key string) string { if self == nil { - return nil - } - - result, found := findParam(self.Request.Query, key) - if found { - return &value{data: result} + return "" } - return nil + return findParam(self.RequestInfo.Query, key) } -func (self *request) Header(key string) *value { +func (self *RequestData) Header(key string) string { if self == nil { - return nil + return "" } - result, found := findParam(self.Request.Headers, key) - if found { - return &value{data: result} + return findParam(self.RequestInfo.Headers, key) +} + +func findParam(params []Param, key string) string { + for _, param := range params { + if param.Key == key { + return param.Value + } } - return nil + return "" } diff --git a/utils/meta/sorting.go b/utils/meta/sorting.go new file mode 100644 index 0000000..93788f0 --- /dev/null +++ b/utils/meta/sorting.go @@ -0,0 +1,39 @@ +package meta + +import ( + "slices" + + "github.com/gofiber/fiber/v2" + "gorm.io/gorm" +) + +type Sorting struct { + Field string + Direction string +} + +func Sort(context *fiber.Ctx, allowedFields []string, fallbackField string) Sorting { + requestData := Request(context) + + field := fallbackField + direction := "desc" + + if sortValue := requestData.Query("sort"); sortValue != "" { + if slices.Contains(allowedFields, sortValue) { + field = sortValue + } + } + + if orderValue := requestData.Query("order"); orderValue != "" { + switch orderValue { + case "asc", "desc": + direction = orderValue + } + } + + return Sorting{Field: field, Direction: direction} +} + +func (self Sorting) Apply(query *gorm.DB) *gorm.DB { + return query.Order(self.Field + " " + self.Direction) +} diff --git a/utils/meta/types.go b/utils/meta/types.go deleted file mode 100644 index c7b8e4d..0000000 --- a/utils/meta/types.go +++ /dev/null @@ -1,26 +0,0 @@ -package meta - -import ( - "dove/types" - - "github.com/gofiber/fiber/v2" -) - -type request struct { - types.Request - context *fiber.Ctx -} - -type value struct { - data string -} - -type Pagination struct { - Page int - PerPage int -} - -type Sorting struct { - Field string - Direction string -} diff --git a/utils/meta/value.go b/utils/meta/value.go deleted file mode 100644 index 889ba0e..0000000 --- a/utils/meta/value.go +++ /dev/null @@ -1,35 +0,0 @@ -package meta - -import ( - "dove/messages" - "dove/utils/logger" -) - -func (self *value) String() string { - if self == nil { - return "" - } - - return self.data -} - -func (self *value) Exists() bool { - return self != nil -} - -func (self *value) Or(fallback string) string { - if self == nil { - return fallback - } - - return self.data -} - -func (self *value) Required() string { - if self == nil { - logger.Errorf(LOG_PREFIX, messages.MetaRequiredValueMissing) - return "" - } - - return self.data -} 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 + } +} diff --git a/utils/toml/load.go b/utils/toml/load.go index 7b3c31a..71fd0c0 100644 --- a/utils/toml/load.go +++ b/utils/toml/load.go @@ -8,7 +8,7 @@ import ( "dove/utils/errors" ) -var loadedData collections.Record[any] +var loadedData collections.Record[string, any] func LoadFile(filePath string) error { fileContent, readError := os.ReadFile(filePath) @@ -16,6 +16,6 @@ func LoadFile(filePath string) error { return errors.Error(messages.ConfigFileReadFailed, filePath, readError.Error()) } - loadedData = make(collections.Record[any]) + loadedData = make(collections.Record[string, any]) return unmarshalContent(fileContent, &loadedData) } diff --git a/utils/urls/attach.go b/utils/urls/attach.go index df8a11a..baf9929 100644 --- a/utils/urls/attach.go +++ b/utils/urls/attach.go @@ -1,10 +1,6 @@ package urls -import ( - "dove/enums" - - "github.com/gofiber/fiber/v2" -) +import "github.com/gofiber/fiber/v2" func Attach(application *fiber.App) { registry.Mutex.Lock() @@ -15,21 +11,21 @@ func Attach(application *fiber.App) { } } -func bindRoute(application *fiber.App, route registeredRoute) { +func bindRoute(application *fiber.App, route RegisteredRoute) { switch route.Method { - case enums.Delete: + case Delete: application.Delete(route.FullPath, route.Handler) - case enums.Get: + case Get: application.Get(route.FullPath, route.Handler) - case enums.Head: + case Head: application.Head(route.FullPath, route.Handler) - case enums.Options: + case Options: application.Options(route.FullPath, route.Handler) - case enums.Patch: + case Patch: application.Patch(route.FullPath, route.Handler) - case enums.Post: + case Post: application.Post(route.FullPath, route.Handler) - case enums.Put: + case Put: application.Put(route.FullPath, route.Handler) } } diff --git a/utils/urls/functions.go b/utils/urls/functions.go deleted file mode 100644 index 6561025..0000000 --- a/utils/urls/functions.go +++ /dev/null @@ -1,30 +0,0 @@ -package urls - -import "strings" - -func resolveFullName(namespace string, name string) string { - switch namespace { - case "": - return name - default: - return namespace + "." + name - } -} - -func resolveFullPath(namespace string, path string) string { - switch namespace { - case "": - return ensureLeadingSlash(path) - default: - return "/" + namespace + ensureLeadingSlash(path) - } -} - -func ensureLeadingSlash(path string) string { - switch strings.HasPrefix(path, "/") { - case true: - return path - default: - return "/" + path - } -} diff --git a/utils/urls/path.go b/utils/urls/path.go index b865676..a3b3ec9 100644 --- a/utils/urls/path.go +++ b/utils/urls/path.go @@ -1,12 +1,24 @@ package urls import ( - "dove/enums" + "strings" "github.com/gofiber/fiber/v2" ) -func Path(method enums.HTTPMethod, path string, handler fiber.Handler, name string) { +type HTTPMethod string + +const ( + Delete HTTPMethod = "DELETE" + Get HTTPMethod = "GET" + Head HTTPMethod = "HEAD" + Options HTTPMethod = "OPTIONS" + Patch HTTPMethod = "PATCH" + Post HTTPMethod = "POST" + Put HTTPMethod = "PUT" +) + +func Path(method HTTPMethod, path string, handler fiber.Handler, name string) { registry.Mutex.Lock() defer registry.Mutex.Unlock() @@ -14,7 +26,7 @@ func Path(method enums.HTTPMethod, path string, handler fiber.Handler, name stri fullName := resolveFullName(namespace, name) fullPath := resolveFullPath(namespace, path) - registry.Routes[fullName] = registeredRoute{ + registry.Routes[fullName] = RegisteredRoute{ Method: method, Path: path, Handler: handler, @@ -35,3 +47,30 @@ func GetFullPath(routeName string) (string, bool) { return route.FullPath, true } + +func resolveFullName(namespace string, name string) string { + switch namespace { + case "": + return name + default: + return namespace + "." + name + } +} + +func resolveFullPath(namespace string, path string) string { + switch namespace { + case "": + return ensureLeadingSlash(path) + default: + return "/" + namespace + ensureLeadingSlash(path) + } +} + +func ensureLeadingSlash(path string) string { + switch strings.HasPrefix(path, "/") { + case true: + return path + default: + return "/" + path + } +} diff --git a/utils/urls/registry.go b/utils/urls/registry.go index a713315..e95d30c 100644 --- a/utils/urls/registry.go +++ b/utils/urls/registry.go @@ -1,9 +1,30 @@ package urls -import "dove/utils/collections" +import ( + "sync" -var registry = &routeRegistry{ - Routes: make(collections.Record[registeredRoute]), + "dove/utils/collections" + + "github.com/gofiber/fiber/v2" +) + +type RegisteredRoute struct { + Method HTTPMethod + Path string + Handler fiber.Handler + Namespace string + Name string + FullPath string +} + +type RouteRegistry struct { + Mutex sync.Mutex + CurrentNamespace string + Routes collections.Record[string, RegisteredRoute] +} + +var registry = &RouteRegistry{ + Routes: make(collections.Record[string, RegisteredRoute]), } func SetNamespace(namespace string) { diff --git a/utils/urls/types.go b/utils/urls/types.go deleted file mode 100644 index 499635b..0000000 --- a/utils/urls/types.go +++ /dev/null @@ -1,25 +0,0 @@ -package urls - -import ( - "sync" - - "dove/enums" - "dove/utils/collections" - - "github.com/gofiber/fiber/v2" -) - -type registeredRoute struct { - Method enums.HTTPMethod - Path string - Handler fiber.Handler - Namespace string - Name string - FullPath string -} - -type routeRegistry struct { - Mutex sync.Mutex - CurrentNamespace string - Routes collections.Record[registeredRoute] -} |
