diff --git a/cmd/web/handlers.go b/cmd/web/handlers.go index 56e2345..1f46db0 100644 --- a/cmd/web/handlers.go +++ b/cmd/web/handlers.go @@ -6,18 +6,17 @@ import ( "fmt" "net/http" "strconv" - "strings" - "unicode/utf8" "gitea.local.lab/Lbenedar/snippetbox/internal/models" + "gitea.local.lab/Lbenedar/snippetbox/internal/validator" "github.com/julienschmidt/httprouter" ) type snippetCreateForm struct { - Title string - Content string - Expires int - FieldErrors map[string]string + Title string + Content string + Expires int + validator.Validator } func (app *application) render(w http.ResponseWriter, status int, page string, data *templateData) { @@ -102,27 +101,17 @@ func (app *application) snippetCreatePost(w http.ResponseWriter, r *http.Request } form := snippetCreateForm{ - Title: r.PostForm.Get("title"), - Content: r.PostForm.Get("content"), - Expires: expires, - FieldErrors: map[string]string{}, + Title: r.PostForm.Get("title"), + Content: r.PostForm.Get("content"), + Expires: expires, } - if strings.TrimSpace(form.Title) == "" { - form.FieldErrors["title"] = "This field cannot be blank" - } else if utf8.RuneCountInString(form.Title) > 100 { - form.FieldErrors["title"] = "This field cannot be more than 100 character long" - } + form.CheckField(validator.NotBlank(form.Title), "title", "This field cannot be blank") + form.CheckField(validator.MaxChars(form.Title, 100), "title", "This field cannot be more than 100 character long") + form.CheckField(validator.NotBlank(form.Content), "content", "This field cannot be blank") + form.CheckField(validator.PermittedInt(form.Expires, 1, 7, 365), "expires", "This field must equal 1, 7 and 365") - if strings.TrimSpace(form.Content) == "" { - form.FieldErrors["content"] = "This field cannot be blank" - } - - if form.Expires != 1 && form.Expires != 7 && form.Expires != 365 { - form.FieldErrors["expires"] = "This field must equal 1, 7 and 365" - } - - if len(form.FieldErrors) > 0 { + if !form.Valid() { data := app.newTemplateData(r) data.Form = form app.render(w, http.StatusUnprocessableEntity, "create.tmpl", data) diff --git a/internal/validator/validator.go b/internal/validator/validator.go new file mode 100644 index 0000000..0248f44 --- /dev/null +++ b/internal/validator/validator.go @@ -0,0 +1,46 @@ +package validator + +import ( + "strings" + "unicode/utf8" +) + +type Validator struct { + FieldErrors map[string]string +} + +func (v *Validator) Valid() bool { + return len(v.FieldErrors) == 0 +} + +func (v *Validator) AddFieldError(key, message string) { + if v.FieldErrors == nil { + v.FieldErrors = make(map[string]string) + } + if _, exist := v.FieldErrors[key]; !exist { + v.FieldErrors[key] = message + } +} + +func (v *Validator) CheckField(ok bool, key, message string) { + if !ok { + v.AddFieldError(key, message) + } +} + +func NotBlank(value string) bool { + return strings.TrimSpace(value) != "" +} + +func MaxChars(value string, n int) bool { + return utf8.RuneCountInString(value) <= n +} + +func PermittedInt(value int, permittedValues ...int) bool { + for i := range permittedValues { + if value == permittedValues[i] { + return true + } + } + return false +}