validation.go 1013 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. package gin
  2. import (
  3. "errors"
  4. "reflect"
  5. "strings"
  6. )
  7. func Validate(c *Context, obj interface{}) error {
  8. var err error
  9. typ := reflect.TypeOf(obj)
  10. val := reflect.ValueOf(obj)
  11. if typ.Kind() == reflect.Ptr {
  12. typ = typ.Elem()
  13. val = val.Elem()
  14. }
  15. for i := 0; i < typ.NumField(); i++ {
  16. field := typ.Field(i)
  17. fieldValue := val.Field(i).Interface()
  18. zero := reflect.Zero(field.Type).Interface()
  19. // Validate nested and embedded structs (if pointer, only do so if not nil)
  20. if field.Type.Kind() == reflect.Struct ||
  21. (field.Type.Kind() == reflect.Ptr && !reflect.DeepEqual(zero, fieldValue)) {
  22. err = Validate(c, fieldValue)
  23. }
  24. if strings.Index(field.Tag.Get("binding"), "required") > -1 {
  25. if reflect.DeepEqual(zero, fieldValue) {
  26. name := field.Name
  27. if j := field.Tag.Get("json"); j != "" {
  28. name = j
  29. } else if f := field.Tag.Get("form"); f != "" {
  30. name = f
  31. }
  32. err = errors.New("Required " + name)
  33. c.Error(err, "json validation")
  34. }
  35. }
  36. }
  37. return err
  38. }