lets-go:8.5 validation helpers
This commit is contained in:
parent
fd514a4580
commit
1541305022
@ -5,11 +5,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"snippetbox.chaosfem.tw/internal/models"
|
"snippetbox.chaosfem.tw/internal/models"
|
||||||
|
"snippetbox.chaosfem.tw/internal/validator"
|
||||||
)
|
)
|
||||||
|
|
||||||
// home ...
|
// home ...
|
||||||
@ -67,7 +66,7 @@ type snippetCreateForm struct {
|
|||||||
Title string
|
Title string
|
||||||
Content string
|
Content string
|
||||||
Expires int
|
Expires int
|
||||||
FieldErrors map[string]string
|
validator.Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
// snippetCreatePost ...
|
// snippetCreatePost ...
|
||||||
@ -88,24 +87,14 @@ func (app *application) snippetCreatePost(w http.ResponseWriter, r *http.Request
|
|||||||
Title: r.PostForm.Get("title"),
|
Title: r.PostForm.Get("title"),
|
||||||
Content: r.PostForm.Get("content"),
|
Content: r.PostForm.Get("content"),
|
||||||
Expires: expires,
|
Expires: expires,
|
||||||
FieldErrors: map[string]string{},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(form.Title) == "" {
|
form.CheckField(validator.NotBlank(form.Title), "title", "This field cannot be blank")
|
||||||
form.FieldErrors["title"] = "This field cannot be blank"
|
form.CheckField(validator.MaxChars(form.Title, 100), "title", "This field cannot be more than 100 characters long")
|
||||||
} else if utf8.RuneCountInString(form.Title) > 100 {
|
form.CheckField(validator.NotBlank(form.Content), "content", "This field cannot be blank")
|
||||||
form.FieldErrors["title"] = "This field cannot contain more than 100 characters"
|
form.CheckField(validator.PermittedValue(form.Expires, 1, 7, 365), "expires", "This field must equal 1, 7 or 365")
|
||||||
}
|
|
||||||
|
|
||||||
if strings.TrimSpace(form.Content) == "" {
|
if !form.Valid() {
|
||||||
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 or 365"
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(form.FieldErrors) > 0 {
|
|
||||||
data := app.newTemplateData(r)
|
data := app.newTemplateData(r)
|
||||||
data.Form = form
|
data.Form = form
|
||||||
app.render(w, r, http.StatusUnprocessableEntity, "create.tmpl", data)
|
app.render(w, r, http.StatusUnprocessableEntity, "create.tmpl", data)
|
||||||
|
47
snippetbox/internal/validator/validator.go
Normal file
47
snippetbox/internal/validator/validator.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Validator struct {
|
||||||
|
FieldErrors map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid() ...
|
||||||
|
func (v *Validator) Valid() bool {
|
||||||
|
return len(v.FieldErrors) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddFieldError ...
|
||||||
|
func (v *Validator) AddFieldError(key, message string) {
|
||||||
|
if v.FieldErrors == nil {
|
||||||
|
v.FieldErrors = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := v.FieldErrors[key]; !exists {
|
||||||
|
v.FieldErrors[key] = message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckField ...
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// PermittedValue[T comparable] ...
|
||||||
|
func PermittedValue[T comparable](value T, permittedValues ...T) bool {
|
||||||
|
return slices.Contains(permittedValues, value)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user