validate.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package form
  2. import (
  3. "net/http"
  4. "reflect"
  5. )
  6. /* ValidateForm parses a POST form into pre-defined struct */
  7. func ValidateForm(r *http.Request, p interface{}) error {
  8. /* only support POST methods */
  9. if r.Method != "POST" {
  10. return EInvalidMethod
  11. }
  12. /* parse POST data into form */
  13. if err := r.ParseForm(); err != nil {
  14. return err
  15. }
  16. var FormError error
  17. /* Parse form data into interface */
  18. formStruct := reflect.ValueOf(p).Elem()
  19. /* populate FormField value */
  20. for HttpFormField, HttpFormValue := range r.Form {
  21. for n := 0; n < formStruct.NumField(); n++ {
  22. fieldt := formStruct.Type().Field(n)
  23. /* get n-th field */
  24. fieldn := formStruct.Field(n)
  25. /* only proceed if field name or tag matches that of form field */
  26. if fieldn.Field(0).String() != HttpFormField {
  27. if fieldt.Name != HttpFormField {
  28. if fieldt.Tag.Get("form") != HttpFormField {
  29. continue
  30. }
  31. }
  32. }
  33. /* set form data to field
  34. equivalent of form.Value = HttpFormValue[0] */
  35. fieldn.Field(2).Set(reflect.ValueOf(HttpFormValue[0]))
  36. }
  37. }
  38. /* run form field validators */
  39. for n := 0; n < formStruct.NumField(); n++ {
  40. fieldn := formStruct.Field(n)
  41. field := fieldn.Interface().(FormField)
  42. if field.Validators == nil {
  43. continue
  44. }
  45. /* prepare list of FormField errors */
  46. var errors []error
  47. for _, validator := range *field.Validators {
  48. if err := validator(field, r.Context()); err != nil {
  49. errors = append(errors, err)
  50. FormError = err
  51. }
  52. }
  53. if len(errors) != 0 {
  54. fieldn.Field(1).Set(reflect.ValueOf(errors))
  55. }
  56. }
  57. /* return status */
  58. return FormError
  59. }