Skip to content

Commit

Permalink
Merge pull request #41 from Rhyanz46/dev
Browse files Browse the repository at this point in the history
add custom message for unique value
  • Loading branch information
Rhyanz46 authored Sep 11, 2024
2 parents aab2a98 + 55eaab7 commit 5bd51d5
Show file tree
Hide file tree
Showing 10 changed files with 329 additions and 34 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ go get github.com/Rhyanz46/go-map-validator/map_validator
- on invalid regex message : ✅ ready
- on type not match message : ✅ ready
- on min/max data message : ✅ ready
- on unique values error : ✅ ready
- on null data message : ⌛ not ready
- on unique values error : ⌛ not ready
- on enum value not match : ⌛ not ready
- on `RequiredWithout` error : ⌛ not ready

Expand All @@ -57,7 +57,7 @@ go get github.com/Rhyanz46/go-map-validator/map_validator


## Road Map

- errors detail mode
- get from urls params http
- validation for `base64`
- handle file size on multipart
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ module github.com/Rhyanz46/go-map-validator

go 1.20

require github.com/google/uuid v1.4.0
require github.com/google/uuid v1.6.0
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
32 changes: 31 additions & 1 deletion map_validator/chain_test.go → map_validator/chain_tree_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package map_validator

import "testing"
import (
"testing"
)

func TestSetKey(t *testing.T) {
root := newChainer().SetKey("root")
Expand Down Expand Up @@ -108,3 +110,31 @@ func TestMultipleLevelChildren(t *testing.T) {

root.GetResult().GetAllKeys()
}

func TestChainValues(T *testing.T) {
root := newChainer().SetKey("root")
childa_1 := root.AddChild().SetKeyValue("childa_1", "value+childa_1")
childa_2 := root.AddChild().SetKeyValue("childa_2", "value+childa_2")
root.AddChild().SetKeyValue("childa_3", "value+childa_3")

childa_1.AddChild().SetKeyValue("childb_1_d", "value+childb_d")
childa_2.AddChild().SetKeyValue("childa_2_x", "value+a").SetUniques([]string{"childa_2_z", "childa_2_y"})
childa_2.AddChild().SetKeyValue("childa_2_z", "value+a")
childa_2.AddChild().SetKeyValue("childa_2_y", "value+ka")
childa_2.AddChild().SetKeyValue("childa_2_sssy", nil)
childa_2.AddChild().SetKeyValue("childa_2_m", "value+a")
childa_2.AddChild().SetKeyValue("childa_2_g", "value+childa_2_g")
childa_2.AddChild().SetKeyValue("childa_2_s", "value+childa_2_s")
childa_2.AddChild().SetKeyValue("childa_2_e", "value+childa_2_e")

childa_1.AddChild().SetKeyValue("childa_1_e", "value+childa_1_e")
childa_1.AddChild().SetKeyValue("childa_1_f", "value+childa_1_f").SetUniques([]string{"childa_1_t"})
childa_1.AddChild().SetKeyValue("childa_1_t", "value+childa_1_e").SetUniques([]string{"childa_1_e"})

root.GetResult().RunUniqueChecker()
res := root.GetResult()
errors := res.GetErrors()
if len(errors) != 2 {
T.Errorf("Expected have two errors, but we got %d error", len(errors))
}
}
42 changes: 23 additions & 19 deletions map_validator/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ func buildMessage(msg string, meta MessageMeta) error {
actualLengthVar := "${actual_length}"
expectedMinLengthVar := "${expected_min_length}"
expectedMaxLengthVar := "${expected_max_length}"
uniqueOriginVar := "${unique_origin}"
uniqueTargetVar := "${unique_target}"
if strings.Contains(msg, fieldVar) {
if meta.Field != nil {
v := *meta.Field
Expand Down Expand Up @@ -106,6 +108,18 @@ func buildMessage(msg string, meta MessageMeta) error {
msg = strings.ReplaceAll(msg, expectedMaxLengthVar, fmt.Sprintf("%v", v))
}
}
if strings.Contains(msg, uniqueOriginVar) {
if meta.Field != nil {
v := *meta.UniqueOrigin
msg = strings.ReplaceAll(msg, uniqueOriginVar, v)
}
}
if strings.Contains(msg, uniqueTargetVar) {
if meta.Field != nil {
v := *meta.UniqueTarget
msg = strings.ReplaceAll(msg, uniqueTargetVar, v)
}
}
return errors.New(msg)
}

Expand Down Expand Up @@ -135,28 +149,18 @@ func validateRecursive(pChain ChainerType, wrapper *RulesWrapper, key string, da
cChain.SetValue(res)
}

// check unique values
if wrapper != nil && res != nil && len(rule.Unique) > 0 {
for _, unique := range rule.Unique {
if wrapper.uniqueValues == nil {
wrapper.uniqueValues = &map[string]map[string]interface{}{}
}

if _, exists := (*wrapper.uniqueValues)[unique]; !exists {
(*wrapper.uniqueValues)[unique] = make(map[string]interface{})
}
if wrapper != nil {
// add unique values
if res != nil && len(rule.Unique) > 0 {
cChain.SetUniques(rule.Unique)
}

for keyX, val := range (*wrapper.uniqueValues)[unique] {
if val == res {
return nil, fmt.Errorf("value of '%s' and '%s' fields must be different", keyX, key)
}
}
(*wrapper.uniqueValues)[unique][key] = res
// add custom message values
if res != nil && rule.CustomMsg.isNotNil() {
cChain.SetCustomMsg(&rule.CustomMsg)
}
}

// put filled and null fields
if wrapper != nil {
// put filled and null fields
if wrapper.filledField == nil {
wrapper.filledField = &[]string{}
}
Expand Down
7 changes: 7 additions & 0 deletions map_validator/implements.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ func (state *finalOperation) RunValidate() (*ExtraOperationData, error) {
return nil, err
}

chainRes.RunUniqueChecker()
for _, err = range chainRes.GetErrors() {
if err != nil {
return nil, err
}
}

manipulatedData := chainRes.ToMap()
extraData := &ExtraOperationData{
rules: state.rules,
Expand Down
11 changes: 11 additions & 0 deletions map_validator/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ type ChainResultType interface {
PrintHierarchyWithSeparator(separator string, currentPath string)
ToMap() map[string]interface{}
RunManipulator() error
RunUniqueChecker()
GetErrors() []error
}

type ChainerType interface {
Expand All @@ -51,11 +53,20 @@ type ChainerType interface {
Forward(index int) ChainerType
SetKey(name string) ChainerType
GetKey() string
SetKeyValue(key string, value interface{}) ChainerType
GetParentKeys() []string
AddChild() ChainerType
LoadFromMap(data map[string]interface{})
SetValue(value interface{}) ChainerType
GetValue() interface{}
SetManipulator(manipulator *func(interface{}) (interface{}, error)) ChainerType
SetUniques(uniques []string) ChainerType
SetCustomMsg(customMsg *CustomMsg) ChainerType
GetUniques() []string
AddError(err error) ChainerType
GetResult() ChainResultType

GetChildren() []ChainerType
GetParent() ChainerType
GetBrothers() []ChainerType
}
54 changes: 50 additions & 4 deletions map_validator/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type MessageMeta struct {
ExpectedMinLength *int64
ExpectedMaxLength *int64
ActualType *reflect.Kind
UniqueOrigin *string
UniqueTarget *string
}

type EnumField[T any] struct {
Expand All @@ -31,6 +33,49 @@ type CustomMsg struct {
OnMax *string
OnMin *string
OnRegexString *string
OnUnique *string
}

func (cm *CustomMsg) uniqueNotNil() bool {
return cm.OnUnique != nil
}

func (cm *CustomMsg) maxNotNil() bool {
return cm.OnMax != nil
}

func (cm *CustomMsg) minNotNil() bool {
return cm.OnMin != nil
}

func (cm *CustomMsg) regexNotNil() bool {
return cm.OnRegexString != nil
}

func (cm *CustomMsg) typeNotMatchNotNil() bool {
return cm.OnTypeNotMatch != nil
}

func (cm *CustomMsg) isNotNil() (notNil bool) {
if cm == nil {
return
}
if cm.OnTypeNotMatch != nil {
notNil = true
}
if cm.OnMax != nil {
notNil = true
}
if cm.OnMin != nil {
notNil = true
}
if cm.OnRegexString != nil {
notNil = true
}
if cm.OnUnique != nil {
notNil = true
}
return notNil
}

type Setting struct {
Expand Down Expand Up @@ -66,10 +111,11 @@ type Rules struct {
File bool
RegexString string
Unique []string
RequiredWithout []string
RequiredIf []string
Object *RulesWrapper
ListObject *RulesWrapper

RequiredWithout []string
RequiredIf []string
Object *RulesWrapper
ListObject *RulesWrapper

CustomMsg CustomMsg // will support soon
}
Expand Down
Loading

0 comments on commit 5bd51d5

Please sign in to comment.