/* * Micro Service * Package: gitlab.hexacode.org/go-libs/microservice * Maintainer: Azzis Arswendo * * Copyright (C) 2023 Hexacode Teknologi Indonesia * All Rights Reserved */ package validate import ( "strings" "gitlab.hexacode.org/go-libs/hctypes" ) type Options struct { Name string `json:"name,omitempty"` Label string `json:"label,omitempty"` Placeholder string `json:"placeholder,omitempty"` Type string `json:"type,omitempty"` Required bool `json:"required,omitempty"` Regex string `json:"regex,omitempty"` Min int `json:"min,omitempty"` Max int `json:"max,omitempty"` MinFloat float32 `json:"min_float,omitempty"` MaxFloat float32 `json:"max_float,omitempty"` Children []*Options `json:"children,omitempty"` ValueText string `json:"value_text,omitempty"` ValueNumber int64 `json:"value_number,omitempty"` ValueFloat float32 `json:"value_float,omitempty"` ValueDouble float64 `json:"value_double,omitempty"` } type ValidateError struct { Name string `json:"name,omitempty"` Message string `json:"message,omitempty"` Value interface{} `json:"value,omitempty"` Children []*ValidateError `json:"children,omitempty"` } func Validate(optionses []*Options, values hctypes.Dict) []*ValidateError { errors := []*ValidateError{} for _, param_opt := range optionses { var value interface{} children := false switch param_opt.Type { case "string", "text", "textnumber", "username", "name", "email", "phone", "password": val, ok := values[param_opt.Name].(hctypes.String) if ok { value = string(val) } else { value = "" } case "number": val, ok := values[param_opt.Name].(hctypes.Float64) if ok { value = int64(val) } else { value = 0 } case "float": val, ok := values[param_opt.Name].(hctypes.Float64) if ok { value = float32(val) } else { value = 0 } case "double": val, ok := values[param_opt.Name].(hctypes.Float64) if ok { value = float64(val) } else { value = 0 } case "dict": children = true val, ok := values[param_opt.Name].(hctypes.Dict) if !ok { err := &ValidateError{ Name: param_opt.Name, Message: "required", } errors = append(errors, err) } if val == nil { err := &ValidateError{ Name: param_opt.Name, Message: "required", } errors = append(errors, err) } errs := Validate(param_opt.Children, val) if len(errs) > 0 { errors = append(errors, &ValidateError{ Name: param_opt.Name, Message: "required", Children: errs, }) } } if !children { err := param_opt.Validate(value) if err != nil { errors = append(errors, err) } } } return errors } func (options *Options) check(value interface{}) error { switch options.Type { case "string": options.ValueText = value.(string) return options.ValidText() case "text": options.ValueText = value.(string) return options.ValidText() case "textnumber": options.ValueText = value.(string) return options.ValidTextNumber() case "number": options.ValueNumber = value.(int64) return options.ValidNumber() case "float": options.ValueFloat = value.(float32) return options.ValidFload() case "double": options.ValueDouble = value.(float64) return options.ValidDouble() case "name": options.ValueText = value.(string) return options.ValidName() case "username": options.ValueText = value.(string) return options.ValidUsername() case "phone": options.ValueText = value.(string) return options.ValidPhone() case "email": options.ValueText = value.(string) return options.ValidEmail() case "password": options.ValueText = value.(string) return options.ValidPassword() } return nil } func (options *Options) Validate(value interface{}) *ValidateError { err := options.check(value) options.ValueText = "" options.ValueNumber = 0 options.ValueFloat = 0 options.ValueDouble = 0 if err != nil { s_err := err.Error() a_err := strings.Split(s_err, ": ") if len(a_err) > 1 { s_err = a_err[1] } return &ValidateError{ Name: options.Name, Message: s_err, Value: value, } } return nil }