package contact import ( "net/mail" "strings" "unicode/utf8" ) const ( maxNameLen = 120 maxEmailLen = 254 maxMessageLen = 8000 minMessageLen = 10 ) // Submission is validated contact form input. type Submission struct { Name string Email string Message string } // Errors maps field names to user-facing messages. type Errors map[string]string func (e Errors) Any() bool { return len(e) > 0 } // Parse reads and validates a contact form POST. func Parse(name, email, message string) (Submission, Errors) { errs := make(Errors) name = strings.TrimSpace(name) email = strings.TrimSpace(email) message = strings.TrimSpace(message) if name == "" { errs["name"] = "Name is required." } else if utf8.RuneCountInString(name) > maxNameLen { errs["name"] = "Name is too long." } if email == "" { errs["email"] = "Email is required." } else if utf8.RuneCountInString(email) > maxEmailLen { errs["email"] = "Email is too long." } else if _, err := mail.ParseAddress(email); err != nil { errs["email"] = "Enter a valid email address." } if message == "" { errs["message"] = "Message is required." } else if utf8.RuneCountInString(message) < minMessageLen { errs["message"] = "Message must be at least 10 characters." } else if utf8.RuneCountInString(message) > maxMessageLen { errs["message"] = "Message is too long." } if errs.Any() { return Submission{}, errs } return Submission{Name: name, Email: email, Message: message}, nil }