123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- package valid
- import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "sort"
- "strings"
- "text/template"
- )
- var (
- // ErrStructPointer is the error that a struct being validated is not specified as a pointer.
- ErrStructPointer = errors.New("only a pointer to a struct can be validated")
- )
- // ErrorTag is the struct tag name used to customize the error field name for a struct field.
- var ErrorTag = "json"
- // Error interface represents an validation error
- type Error interface {
- Error() string
- Code() string
- Message() string
- SetMessage(string) Error
- Params() map[string]interface{}
- SetParams(map[string]interface{}) Error
- }
- // InternalError represents an error that should NOT be treated as a validation error.
- type InternalError interface {
- error
- InternalError() error
- }
- type internalError struct {
- error
- }
- // NewInternalError wraps a given error into an InternalError.
- func NewInternalError(err error) InternalError {
- return internalError{error: err}
- }
- // InternalError returns the actual error that it wraps around.
- func (e internalError) InternalError() error {
- return e.error
- }
- // Errors represents the validation errors that are indexed by struct field names, map or slice keys.
- // values are Error or Errors (for map, slice and array error value is Errors).
- type Errors map[string]error
- // Error returns the error string of Errors.
- func (es Errors) Error() string {
- if len(es) == 0 {
- return ""
- }
- keys := make([]string, len(es))
- i := 0
- for key := range es {
- keys[i] = key
- i++
- }
- sort.Strings(keys)
- var s strings.Builder
- for i, key := range keys {
- if i > 0 {
- s.WriteString("; ")
- }
- if errs, ok := es[key].(Errors); ok {
- _, _ = fmt.Fprintf(&s, "%v: (%v)", key, errs)
- } else {
- _, _ = fmt.Fprintf(&s, "%v: %v", key, es[key].Error())
- }
- }
- s.WriteString(".")
- return s.String()
- }
- // MarshalJSON converts the Errors into a valid JSON.
- func (es Errors) MarshalJSON() ([]byte, error) {
- errs := map[string]interface{}{}
- for key, err := range es {
- if ms, ok := err.(json.Marshaler); ok {
- errs[key] = ms
- } else {
- errs[key] = err.Error()
- }
- }
- return json.Marshal(errs)
- }
- // Filter removes all nils from Errors and returns back the updated Errors as an error.
- // If the length of Errors becomes 0, it will return nil.
- func (es Errors) Filter() error {
- for key, value := range es {
- if value == nil {
- delete(es, key)
- }
- }
- if len(es) == 0 {
- return nil
- }
- return es
- }
- // NewError create new validation error.
- func NewError(code, message string) Error {
- return ErrorObject{
- code: code,
- message: message,
- }
- }
- // Assert that our ErrorObject implements the Error interface.
- var _ Error = ErrorObject{}
- // ErrorObject is the default validation error
- // that implements the Error interface.
- type ErrorObject struct {
- code string
- message string
- params map[string]interface{}
- }
- // SetCode set the error's translation code.
- func (e ErrorObject) SetCode(code string) Error {
- e.code = code
- return e
- }
- // Code get the error's translation code.
- func (e ErrorObject) Code() string {
- return e.code
- }
- // SetParams set the error's params.
- func (e ErrorObject) SetParams(params map[string]interface{}) Error {
- e.params = params
- return e
- }
- // AddParam add parameter to the error's parameters.
- func (e ErrorObject) AddParam(name string, value interface{}) Error {
- if e.params == nil {
- e.params = make(map[string]interface{})
- }
- e.params[name] = value
- return e
- }
- // Params returns the error's params.
- func (e ErrorObject) Params() map[string]interface{} {
- return e.params
- }
- // SetMessage set the error's message.
- func (e ErrorObject) SetMessage(message string) Error {
- e.message = message
- return e
- }
- // Message return the error's message.
- func (e ErrorObject) Message() string {
- return e.message
- }
- // Error returns the error message.
- func (e ErrorObject) Error() string {
- if len(e.params) == 0 {
- return e.message
- }
- res := bytes.Buffer{}
- _ = template.Must(template.New("err").Parse(e.message)).Execute(&res, e.params)
- return res.String()
- }
- // ErrFieldPointer is the error that a field is not specified as a pointer.
- type ErrFieldPointer int
- // Error returns the error string of ErrFieldPointer.
- func (e ErrFieldPointer) Error() string {
- return fmt.Sprintf("field #%v must be specified as a pointer", int(e))
- }
- // ErrFieldNotFound is the error that a field cannot be found in the struct.
- type ErrFieldNotFound int
- // Error returns the error string of ErrFieldNotFound.
- func (e ErrFieldNotFound) Error() string {
- return fmt.Sprintf("field #%v cannot be found in the struct", int(e))
- }
|