Issue

So I have read the docs and I made my own custom validator to have custom error message formatting instead of the default which formats things that do not match the validation very ugly.

Example:

{"err":"Key: 'User.Email' Error:Field validation for 'Email' failed on the 'required' tag"}

So for that reason I have made my own, and I implemented the interface required for that, in Gin.

But however, even tho I have changed binding.Validator my own validator is not really bound to binding.Validator. I know I could make a global validator intead, but I want to have it into binding.Validator

package main

import (
    "errors"
    "fmt"
    "log"

    "github.com/gin-gonic/gin"
    "github.com/gin-gonic/gin/binding"
    "github.com/go-playground/validator"
)

type (
    User struct {
        Email string `validate:"required,min=3"`
    }
    Validator struct {
        validate *validator.Validate
    }
    ErrorResponse struct {
        Error bool
        FailedField string
        Tag         string
        Value       string
    }
)

func(c Validator) Engine() any {
    return c.validate
}

func(c Validator) ValidateStruct(data any) error {
    Error := &ErrorResponse{}

    err := c.validate.Struct(data); if err != nil {
        for _, err := range err.(validator.ValidationErrors) {
            Error.FailedField = err.Field()
            Error.Tag = err.Tag()
            Error.Value = err.Value().(string)
            Error.Error = true


            // Do not return all errors joined at once
            // bcs thats not a good practice 
            return errors.New(
                fmt.Sprintf("[%s]: '%s' needs to implement '%s'", 
                err.Tag(), 
                err.Value().(string), 
                err.Tag()),
            )
        }
    }
    return nil
}

func main() {
    app := gin.Default()

    XValidator := &Validator{
        validate: validator.New(),
    }

    binding.Validator = XValidator
    vEngine, ok := binding.Validator.Engine().(*validator.Validate); if !ok {
        fmt.Println(ok)
        log.Fatal("Could not load validator engine")
    }

    // Global Error Handler
    app.Use(func(c *gin.Context){
        if len(c.Errors) > 0 {
            c.JSON(403, gin.H{
                "err": c.Errors[0],
            })
        } 
        c.Next()
    })
    app.GET("/", func(c *gin.Context) {
        user := new(User)
        user.Email = "e"

        err := vEngine.Struct(user); if err != nil{
            c.JSON(403, gin.H{
                "err": err.Error(),
            })
            return
        }

        c.JSON(200, gin.H{
            "message": "Hello World",
        })
    })
    app.Run(":2000") 
}