I'm looking to iterate over the string fields of a struct so I can do some clean-up/validation (with strings.TrimSpace
, strings.Trim
, etc).
Right now I have a messy switch-case that's not really scalable, and as this isn't in a hot spot of my application (a web form) it seems leveraging reflect
is a good choice here.
I'm at a bit of a roadblock for how to implement this however, and the reflect docs are a little confusing to me (I've been digging through some other validation packages, but they're way too heavyweight + I'm using gorilla/schema for the unmarshalling part already):
- Iterate over the struct
- For each field of type string, apply whatever I need to from the
strings
package i.e.field = strings.TrimSpace(field)
- If there exists a field.Tag.Get("max"), we'll use that value (strconv.Atoi, then unicode.RuneCountInString)
Provide an error slice that's also compatible with the error interface type
type FormError []string type Listing struct { Title string `max:"50"` Location string `max:"100"` Description string `max:"10000"` ExpiryDate time.Time RenderedDesc template.HTML Contact string `max:"255"` } // Iterate over our struct, fix whitespace/formatting where possible // and return errors encountered func (l *Listing) Validate() error { typ := l.Elem().Type() var invalid FormError for i = 0; i < typ.NumField(); i++ { // Iterate over fields // For StructFields of type string, field = strings.TrimSpace(field) // if field.Tag.Get("max") != "" { // check max length/convert to int/utf8.RuneCountInString if max length exceeded, invalid = append(invalid, "errormsg") } if len(invalid) > 0 { return invalid } return nil } func (f FormError) Error() string { var fullError string for _, v := range f { fullError =+ v + "\n" } return "Errors were encountered during form processing: " + fullError }
Thanks in advance.