diff --git a/errors.go b/errors.go index 2f326a2..2f01a1c 100644 --- a/errors.go +++ b/errors.go @@ -81,7 +81,7 @@ type ( ResultErrorFields } - // ItemsMustBeUniqueError. ErrorDetails: type + // ItemsMustBeUniqueError. ErrorDetails: type, i, j ItemsMustBeUniqueError struct { ResultErrorFields } diff --git a/locales.go b/locales.go index 7bd9a9d..9b4570f 100644 --- a/locales.go +++ b/locales.go @@ -147,7 +147,7 @@ func (l DefaultLocale) ArrayMaxItems() string { } func (l DefaultLocale) Unique() string { - return `{{.type}} items must be unique` + return `{{.type}} items[{{.i}},{{.j}}] must be unique` } func (l DefaultLocale) ArrayContains() string { diff --git a/utils.go b/utils.go index cc3100a..cfd8948 100644 --- a/utils.go +++ b/utils.go @@ -62,6 +62,16 @@ func isStringInSlice(s []string, what string) bool { return false } +// indexStringInSlice returns the index of the first instance of 'what' in s or -1 if it is not found in s. +func indexStringInSlice(s []string, what string) int { + for i := range s { + if s[i] == what { + return i + } + } + return -1 +} + func marshalToJsonString(value interface{}) (*string, error) { mBytes, err := json.Marshal(value) diff --git a/validation.go b/validation.go index 2f1e7df..1c710fa 100644 --- a/validation.go +++ b/validation.go @@ -517,17 +517,17 @@ func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface // uniqueItems: if currentSubSchema.uniqueItems { var stringifiedItems []string - for _, v := range value { + for j, v := range value { vString, err := marshalWithoutNumber(v) if err != nil { result.addInternalError(new(InternalError), context, value, ErrorDetails{"err": err}) } - if isStringInSlice(stringifiedItems, *vString) { + if i := indexStringInSlice(stringifiedItems, *vString); i > -1 { result.addInternalError( new(ItemsMustBeUniqueError), context, value, - ErrorDetails{"type": TYPE_ARRAY}, + ErrorDetails{"type": TYPE_ARRAY, "i": i, "j": j}, ) } stringifiedItems = append(stringifiedItems, *vString)