89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package mila
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
type Config struct {
|
|
MaxRouteLen int
|
|
MaxTextLen int
|
|
MaxTemplateLen int
|
|
}
|
|
|
|
func DefaultConfig() Config {
|
|
return Config{
|
|
MaxRouteLen: 3,
|
|
MaxTextLen: 200,
|
|
MaxTemplateLen: 200,
|
|
}
|
|
}
|
|
|
|
type ValidationError struct {
|
|
Field string `json:"field"`
|
|
Msg string `json:"message"`
|
|
}
|
|
|
|
func (e ValidationError) Error() string {
|
|
return fmt.Sprintf("%s: %s", e.Field, e.Msg)
|
|
}
|
|
|
|
func Validate(cfg Config, state ContentState) error {
|
|
cfg = normalizeConfig(cfg)
|
|
|
|
state.Route = strings.TrimSpace(state.Route)
|
|
state.Template = strings.TrimSpace(state.Template)
|
|
|
|
if state.Route == "" {
|
|
return ValidationError{Field: "route", Msg: "is required"}
|
|
}
|
|
if runeLen(state.Route) > cfg.MaxRouteLen {
|
|
return ValidationError{Field: "route", Msg: fmt.Sprintf("must be at most %d characters", cfg.MaxRouteLen)}
|
|
}
|
|
if !utf8.ValidString(state.Route) {
|
|
return ValidationError{Field: "route", Msg: "must be valid UTF-8"}
|
|
}
|
|
if !utf8.ValidString(state.Text) {
|
|
return ValidationError{Field: "str", Msg: "must be valid UTF-8"}
|
|
}
|
|
if runeLen(state.Text) > cfg.MaxTextLen {
|
|
return ValidationError{Field: "str", Msg: fmt.Sprintf("must be at most %d characters", cfg.MaxTextLen)}
|
|
}
|
|
if state.Template == "" {
|
|
return ValidationError{Field: "tpl_name", Msg: "is required"}
|
|
}
|
|
if !utf8.ValidString(state.Template) {
|
|
return ValidationError{Field: "tpl_name", Msg: "must be valid UTF-8"}
|
|
}
|
|
if runeLen(state.Template) > cfg.MaxTemplateLen {
|
|
return ValidationError{Field: "tpl_name", Msg: fmt.Sprintf("must be at most %d characters", cfg.MaxTemplateLen)}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func IsValidationError(err error) bool {
|
|
var target ValidationError
|
|
return errors.As(err, &target)
|
|
}
|
|
|
|
func normalizeConfig(cfg Config) Config {
|
|
def := DefaultConfig()
|
|
if cfg.MaxRouteLen <= 0 {
|
|
cfg.MaxRouteLen = def.MaxRouteLen
|
|
}
|
|
if cfg.MaxTextLen <= 0 {
|
|
cfg.MaxTextLen = def.MaxTextLen
|
|
}
|
|
if cfg.MaxTemplateLen <= 0 {
|
|
cfg.MaxTemplateLen = def.MaxTemplateLen
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func runeLen(s string) int {
|
|
return utf8.RuneCountInString(s)
|
|
}
|