Files
marktvogt.de/backend/internal/pkg/validate/validate.go
T
vikingowl 3145dba255 fix(lint): resolve all golangci-lint v2 issues
- Disable revive exported/package-comments rules (style, not correctness)
- Use errors.Is instead of == for pgx.ErrNoRows comparisons
- Use errors.As instead of type assertion on validator errors
- Use http.NewRequestWithContext instead of client.Get (noctx)
- Check resp.Body.Close error return (errcheck)
- Run gofmt on files with formatting drift
2026-02-22 10:09:46 +01:00

57 lines
1.4 KiB
Go

package validate
import (
"errors"
"fmt"
"strings"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"marktvogt.de/backend/internal/pkg/apierror"
)
var v = validator.New()
func Struct(s any) *apierror.Error {
if err := v.Struct(s); err != nil {
var ve validator.ValidationErrors
if errors.As(err, &ve) {
var msgs []string
for _, fe := range ve {
msgs = append(msgs, formatFieldError(fe))
}
return apierror.Validation(strings.Join(msgs, "; "))
}
return apierror.Validation(err.Error())
}
return nil
}
func BindJSON(c *gin.Context, dest any) *apierror.Error {
if err := c.ShouldBindJSON(dest); err != nil {
return apierror.BadRequest("invalid_json", fmt.Sprintf("invalid request body: %s", err.Error()))
}
return Struct(dest)
}
func formatFieldError(fe validator.FieldError) string {
field := fe.Field()
switch fe.Tag() {
case "required":
return fmt.Sprintf("%s is required", field)
case "email":
return fmt.Sprintf("%s must be a valid email address", field)
case "min":
return fmt.Sprintf("%s must be at least %s characters", field, fe.Param())
case "max":
return fmt.Sprintf("%s must be at most %s characters", field, fe.Param())
case "gte":
return fmt.Sprintf("%s must be at least %s", field, fe.Param())
case "lte":
return fmt.Sprintf("%s must be at most %s", field, fe.Param())
default:
return fmt.Sprintf("%s failed validation: %s", field, fe.Tag())
}
}