validate.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  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. // only proceed if field name or tag matches that of form field
  24. if fieldt.Name != HttpFormField && fieldt.Tag.Get("form") != HttpFormField {
  25. continue
  26. }
  27. // get n-th field
  28. fieldn := formStruct.Field(n)
  29. // set form data to field
  30. // equivalent of form.Value = HttpFormValue[0]
  31. fieldn.Field(3).Set(reflect.ValueOf(HttpFormValue[0]))
  32. }
  33. }
  34. // run form field validators
  35. for n := 0; n < formStruct.NumField(); n++ {
  36. fieldn := formStruct.Field(n)
  37. field := fieldn.Interface().(FormField)
  38. for _, validator := range *field.Validators {
  39. if err := validator(field, r.Context()); err != nil {
  40. fieldn.Field(4).Set(reflect.ValueOf(err))
  41. FormError = err
  42. break
  43. }
  44. }
  45. }
  46. // return status
  47. return FormError
  48. }