Files
base/pkg/validation/validation.go
2026-04-10 18:25:21 +03:30

155 lines
3.9 KiB
Go

package validation
import (
"math"
"reflect"
"strings"
)
type Error struct {
Message string
}
func (e Error) Error() string {
return e.Message
}
func (e Error) SetMessage(message string) Error {
e.Message = message
return e
}
var ErrBadRequest = Error{Message: "Bad Request"}
// ExistKey checks if a key exists in the map
func ExistKey(key string, mapItem map[string]interface{}, message string) error {
var ok bool
if _, ok = mapItem[key]; !ok {
return ErrBadRequest.SetMessage(message)
}
return nil
}
// NotBlank checks if a value is not blank (not nil, not empty string, not empty slice)
func NotBlank(key string, mapItem map[string]interface{}, message string) error {
if v, ok := mapItem[key]; ok {
// Check for nil value
if v == nil {
return ErrBadRequest.SetMessage(message)
}
// Check for empty string
if str, isString := v.(string); isString && str == "" {
return ErrBadRequest.SetMessage(message)
}
// Check for empty slice
if arr, isSlice := v.([]interface{}); isSlice && len(arr) == 0 {
return ErrBadRequest.SetMessage(message)
}
}
return nil
}
// IsString checks if a value is a string type
func IsString(key string, mapItem map[string]interface{}, message string) error {
if str, ok := mapItem[key]; ok {
if reflect.TypeOf(str).Kind() != reflect.String {
return ErrBadRequest.SetMessage(message)
}
}
return nil
}
// IsInt checks if a value is a valid integer (float64 that can be converted to int)
func IsInt(key string, mapItem map[string]interface{}, message string) error {
if i, ok := mapItem[key]; ok {
if val, okFloat := i.(float64); okFloat {
if val != float64(int(val)) || val > float64(math.MaxUint32) {
return ErrBadRequest.SetMessage(message)
}
} else {
return ErrBadRequest.SetMessage(message)
}
}
return nil
}
// IsFloat64 checks if a value is a float64 type
func IsFloat64(key string, mapItem map[string]interface{}, message string) error {
if i, ok := mapItem[key]; ok {
if _, okFloat := i.(float64); !okFloat {
return ErrBadRequest.SetMessage(message)
}
}
return nil
}
// IsBool checks if a value is a boolean type
func IsBool(key string, mapItem map[string]interface{}, message string) error {
if b, ok := mapItem[key]; ok {
if reflect.TypeOf(b).Kind() != reflect.Bool {
return ErrBadRequest.SetMessage(message)
}
}
return nil
}
// AtLeastOneFieldMustBePresent checks if at least one of the specified fields is present
func AtLeastOneFieldMustBePresent(keys string, mapItem map[string]interface{}, message string) error {
keySlice := strings.Split(keys, ",")
for _, k := range keySlice {
if _, ok := mapItem[k]; ok {
return nil
}
}
return ErrBadRequest.SetMessage(message)
}
// UnexpectedField checks if there are any unexpected fields in the map
func UnexpectedField(keys string, mapItem map[string]interface{}, message string) error {
keySlice := strings.Split(keys, ",")
keySet := make(map[string]bool)
for _, key := range keySlice {
keySet[key] = true
}
for k := range mapItem {
if ok := keySet[k]; !ok {
return ErrBadRequest.SetMessage(message)
}
}
return nil
}
// MaxRange checks if a numeric value is not greater than the maximum
func MaxRange(key string, max int, mapItem map[string]interface{}, message string) error {
if val, ok := mapItem[key]; ok {
if i, okInt := val.(float64); okInt && i > float64(max) {
return ErrBadRequest.SetMessage(message)
}
}
return nil
}
// MinRange checks if a numeric value is not less than the minimum
func MinRange(key string, min int, mapItem map[string]interface{}, message string) error {
if val, ok := mapItem[key]; ok {
if i, okInt := val.(float64); okInt && i < float64(min) {
return ErrBadRequest.SetMessage(message)
}
}
return nil
}
// Contains checks if a value is present in a slice
func Contains(limitedSoftwareTypes []int, currentSoftwareType int) bool {
for _, v := range limitedSoftwareTypes {
if v == currentSoftwareType {
return true
}
}
return false
}