281 lines
5.0 KiB
Go
281 lines
5.0 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
type ValidationError struct {
|
|
Model string
|
|
Field string
|
|
Err error
|
|
}
|
|
|
|
var _ ErrorWithParams = ValidationError{}
|
|
|
|
func (e ValidationError) Error() string {
|
|
prefix := e.Model
|
|
|
|
if e.Field != "" {
|
|
if len(prefix) > 0 {
|
|
prefix += "."
|
|
}
|
|
prefix += e.Field
|
|
}
|
|
|
|
if prefix != "" {
|
|
prefix += ": "
|
|
}
|
|
|
|
return prefix + e.Err.Error()
|
|
}
|
|
|
|
func (e ValidationError) Code() ErrorCode {
|
|
var domainErr Error
|
|
if errors.As(e.Err, &domainErr) {
|
|
return domainErr.Code()
|
|
}
|
|
return ErrorCodeIncorrectInput
|
|
}
|
|
|
|
func (e ValidationError) Slug() string {
|
|
var domainErr Error
|
|
if errors.As(e.Err, &domainErr) {
|
|
return domainErr.Slug()
|
|
}
|
|
return "validation-failed"
|
|
}
|
|
|
|
func (e ValidationError) Params() map[string]any {
|
|
var withParams ErrorWithParams
|
|
if ok := errors.As(e.Err, &withParams); !ok {
|
|
return nil
|
|
}
|
|
return withParams.Params()
|
|
}
|
|
|
|
func (e ValidationError) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
type SliceElementValidationError struct {
|
|
Model string
|
|
Field string
|
|
Index int
|
|
Err error
|
|
}
|
|
|
|
var _ ErrorWithParams = SliceElementValidationError{}
|
|
|
|
func (e SliceElementValidationError) Error() string {
|
|
prefix := e.Model
|
|
|
|
if e.Field != "" {
|
|
if len(prefix) > 0 {
|
|
prefix += "."
|
|
}
|
|
prefix += e.Field + "[" + strconv.Itoa(e.Index) + "]"
|
|
}
|
|
|
|
if prefix != "" {
|
|
prefix += ": "
|
|
}
|
|
|
|
return prefix + e.Err.Error()
|
|
}
|
|
|
|
func (e SliceElementValidationError) Code() ErrorCode {
|
|
var domainErr Error
|
|
if errors.As(e.Err, &domainErr) {
|
|
return domainErr.Code()
|
|
}
|
|
return ErrorCodeIncorrectInput
|
|
}
|
|
|
|
func (e SliceElementValidationError) Slug() string {
|
|
var domainErr Error
|
|
if errors.As(e.Err, &domainErr) {
|
|
return domainErr.Slug()
|
|
}
|
|
return "slice-element-validation-failed"
|
|
}
|
|
|
|
func (e SliceElementValidationError) Params() map[string]any {
|
|
var withParams ErrorWithParams
|
|
if ok := errors.As(e.Err, &withParams); !ok {
|
|
return nil
|
|
}
|
|
return withParams.Params()
|
|
}
|
|
|
|
func (e SliceElementValidationError) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
type MinGreaterEqualError struct {
|
|
Min int
|
|
Current int
|
|
}
|
|
|
|
var _ ErrorWithParams = MinGreaterEqualError{}
|
|
|
|
func (e MinGreaterEqualError) Error() string {
|
|
return fmt.Sprintf("must be no less than %d (current: %d)", e.Min, e.Current)
|
|
}
|
|
|
|
func (e MinGreaterEqualError) Code() ErrorCode {
|
|
return ErrorCodeIncorrectInput
|
|
}
|
|
|
|
func (e MinGreaterEqualError) Slug() string {
|
|
return "min-greater-equal"
|
|
}
|
|
|
|
func (e MinGreaterEqualError) Params() map[string]any {
|
|
return map[string]any{
|
|
"Min": e.Min,
|
|
"Current": e.Current,
|
|
}
|
|
}
|
|
|
|
type MaxLessEqualError struct {
|
|
Max int
|
|
Current int
|
|
}
|
|
|
|
var _ ErrorWithParams = MaxLessEqualError{}
|
|
|
|
func (e MaxLessEqualError) Error() string {
|
|
return fmt.Sprintf("must be no greater than %d (current: %d)", e.Max, e.Current)
|
|
}
|
|
|
|
func (e MaxLessEqualError) Code() ErrorCode {
|
|
return ErrorCodeIncorrectInput
|
|
}
|
|
|
|
func (e MaxLessEqualError) Slug() string {
|
|
return "max-less-equal"
|
|
}
|
|
|
|
func (e MaxLessEqualError) Params() map[string]any {
|
|
return map[string]any{
|
|
"Max": e.Max,
|
|
"Current": e.Current,
|
|
}
|
|
}
|
|
|
|
type LenOutOfRangeError struct {
|
|
Min int
|
|
Max int
|
|
Current int
|
|
}
|
|
|
|
var _ ErrorWithParams = LenOutOfRangeError{}
|
|
|
|
func (e LenOutOfRangeError) Error() string {
|
|
return fmt.Sprintf("length must be between %d and %d (current length: %d)", e.Min, e.Max, e.Current)
|
|
}
|
|
|
|
func (e LenOutOfRangeError) Code() ErrorCode {
|
|
return ErrorCodeIncorrectInput
|
|
}
|
|
|
|
func (e LenOutOfRangeError) Slug() string {
|
|
return "length-out-of-range"
|
|
}
|
|
|
|
func (e LenOutOfRangeError) Params() map[string]any {
|
|
return map[string]any{
|
|
"Min": e.Min,
|
|
"Max": e.Max,
|
|
"Current": e.Current,
|
|
}
|
|
}
|
|
|
|
type InvalidURLError struct {
|
|
URL string
|
|
}
|
|
|
|
var _ ErrorWithParams = InvalidURLError{}
|
|
|
|
func (e InvalidURLError) Error() string {
|
|
return fmt.Sprintf("%s: invalid URL", e.URL)
|
|
}
|
|
|
|
func (e InvalidURLError) Code() ErrorCode {
|
|
return ErrorCodeIncorrectInput
|
|
}
|
|
|
|
func (e InvalidURLError) Slug() string {
|
|
return "invalid-url"
|
|
}
|
|
|
|
func (e InvalidURLError) Params() map[string]any {
|
|
return map[string]any{
|
|
"URL": e.URL,
|
|
}
|
|
}
|
|
|
|
var ErrRequired error = simpleError{
|
|
msg: "can't be blank",
|
|
code: ErrorCodeIncorrectInput,
|
|
slug: "required",
|
|
}
|
|
|
|
var ErrNil error = simpleError{
|
|
msg: "must not be nil",
|
|
code: ErrorCodeIncorrectInput,
|
|
slug: "nil",
|
|
}
|
|
|
|
func validateSliceLen[S ~[]E, E any](s S, min, max int) error {
|
|
if l := len(s); l > max || l < min {
|
|
return LenOutOfRangeError{
|
|
Min: min,
|
|
Max: max,
|
|
Current: l,
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func validateStringLen(s string, min, max int) error {
|
|
if l := len(s); l > max || l < min {
|
|
return LenOutOfRangeError{
|
|
Min: min,
|
|
Max: max,
|
|
Current: l,
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func validateVersionCode(code string) error {
|
|
return validateStringLen(code, versionCodeMinLength, versionCodeMaxLength)
|
|
}
|
|
|
|
func validateServerKey(key string) error {
|
|
return validateStringLen(key, serverKeyMinLength, serverKeyMaxLength)
|
|
}
|
|
|
|
func validateIntInRange(current, min, max int) error {
|
|
if current < min {
|
|
return MinGreaterEqualError{
|
|
Min: min,
|
|
Current: current,
|
|
}
|
|
}
|
|
|
|
if current > max {
|
|
return MaxLessEqualError{
|
|
Max: max,
|
|
Current: current,
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|