Skip to content

Commit

Permalink
Merge pull request #49 from rezakhademix/better-comments
Browse files Browse the repository at this point in the history
better comments
  • Loading branch information
rezakhademix authored Mar 9, 2024
2 parents d9c95f0 + eddc1ea commit c405d16
Show file tree
Hide file tree
Showing 15 changed files with 123 additions and 26 deletions.
12 changes: 10 additions & 2 deletions between.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@ const (
BetweenMsg = "%s should be greater than or equal %v and less than or equal %v"
)

// BetweenInt checks i to be less than or requal given max and more than and equal given min value.
// BetweenInt checks the value under validation to have an integer value between the given min and max.
//
// Example:
//
// validator.BetweenInt(21, 1, 10, "age", "age must be between 1 and 10.")
func (v *Validator) BetweenInt(i, min, max int, field, msg string) *Validator {
v.Check(i >= min && i <= max, field, v.msg(Between, msg, field, min, max))

return v
}

// BetweenFloat checks f to be less than given max value and more than given min value.
// BetweenFloat checks the field under validation to have a float value between the given min and max.
//
// Example:
//
// validator.BetweenFloat(3.5, 2.0, 5.0, "height", "height must be between 2.0 and 5.0 meters.")
func (v *Validator) BetweenFloat(f, min, max float64, field, msg string) *Validator {
v.Check(f >= min && f <= max, field, v.msg(Between, msg, field, min, max))

Expand Down
6 changes: 5 additions & 1 deletion date.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ const (
DateMsg = "%s has wrong date format"
)

// Date checks the field under validation to be a valid, non-relative date.
// Date checks the value under validation to be a valid, non-relative date.
//
// Example:
//
// validator.Date("2024-03-09", "2006-01-02", "birthdate", "birthdate must be a valid date in the format YYYY-MM-DD.")
func (v *Validator) Date(d, layout, field, msg string) *Validator {
_, err := time.Parse(layout, d)
if err != nil {
Expand Down
6 changes: 5 additions & 1 deletion email.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ const (
EmailRegex = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\\])"
)

// Email checks the value of s under validation must match the EmailRegex regular expression.
// Email checks the value under validation must match the EmailRegex regular expression.
//
// Example:
//
// validator.Email("[email protected]", "email", "email address is not valid.")
func (v *Validator) Email(s, field, msg string) *Validator {
v.RegexMatches(s, EmailRegex, field, v.msg(Email, msg, field))

Expand Down
6 changes: 5 additions & 1 deletion exists.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ const (
ExistsMsg = "%s does not exist"
)

// Exists checks if given value exists in desired table or not.
// Exists checks if given value exists in the desired table or not.
//
// Example:
//
// validator.Exists(42, "users", "id", "user_id", "user with id 42 does not exist.")
func (v *Validator) Exists(value any, table, column, field, msg string) *Validator {
v.Check(v.repo.Exists(value, table, column), field, v.msg(Exists, msg, field))

Expand Down
7 changes: 6 additions & 1 deletion in.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package validator

// In checks value under validation must be included in the given list of values
// In checks if the value under validation must be included in the given list of values.
//
// Example:
//
// result := In("apple", "banana", "orange", "apple")
// // result will be true because "apple" is included in the list of acceptable values.
func In[T comparable](value T, acceptableValues ...T) bool {
for i := range acceptableValues {
if value == acceptableValues[i] {
Expand Down
18 changes: 15 additions & 3 deletions len.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,33 @@ const (
LenListMsg = "%s should have %d items"
)

// LenString checks if length of a string equal to give size or not.
// LenString checks if the length of a string is equal to the given size or not.
//
// Example:
//
// validator.LenString("rez", 5, "username", "username must be 5 characters.")
func (v *Validator) LenString(s string, size int, field, msg string) *Validator {
v.Check(len(strings.TrimSpace(s)) == size, field, v.msg(Len, msg, field, size))

return v
}

// LenInt checks if length of an integer is equal to given size or not.
// LenInt checks if the length of the given integer is equal to the given size or not.
//
// Example:
//
// validator.LenInt(12345, 5, "zipcode", "Zip code must be 5 digits long.")
func (v *Validator) LenInt(i, size int, field, msg string) *Validator {
v.Check(len(strconv.Itoa(i)) == size, field, v.msg(Len, msg, field, size))

return v
}

// LenSlice checks if length of a slice is equal to given size or not.
// LenSlice checks if the length of the given slice is equal to the given size or not.
//
// Example:
//
// validator.LenSlice([]int{1, 2, 3, 4, 5}, 5, "numbers", "the list must contain exactly 5 numbers.")
func (v *Validator) LenSlice(s []any, size int, field, msg string) *Validator {
v.Check(len(s) == size, field, v.msg(LenList, msg, field, size))

Expand Down
12 changes: 10 additions & 2 deletions max.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@ const (
MaxMsg = "%s should be less than %v"
)

// MaxInt checks i to be less than given max value
// MaxInt checks if the integer value is less than or equal the given max value.
//
// Example:
//
// validator.MaxInt(10, 100, "age", "age must be less than 100.")
func (v *Validator) MaxInt(i, max int, field, msg string) *Validator {
v.Check(i <= max, field, v.msg(Max, msg, field, max))

return v
}

// MaxFloat checks f to be less than given max value
// MaxFloat checks if the given float value is less than or equal the given max value.
//
// Example:
//
// validator.MaxFloat(3.5, 5.0, "height", "height must be less than 5.0 meters.")
func (v *Validator) MaxFloat(f, max float64, field, msg string) *Validator {
v.Check(f <= max, field, v.msg(Max, msg, field, max))

Expand Down
12 changes: 10 additions & 2 deletions min.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@ const (
MinMsg = "%s should be more than %v"
)

// MinInt checks i to be greater than given min value
// MinInt checks if the given integer value is greater than or equal the given min value.
//
// Example:
//
// validator.MinInt(18, 0, "age", "age must be at least 0.")
func (v *Validator) MinInt(i, min int, field, msg string) *Validator {
v.Check(i >= min, field, v.msg(Min, msg, field, min))

return v
}

// MinFloat checks f to be greater than given min value
// MinFloat checks if the given float value is greater than or equal the given min value.
//
// Example:
//
// validator.MinFloat(5.0, 0.0, "height", "height must be at least 0.0 meters.")
func (v *Validator) MinFloat(f, min float64, field, msg string) *Validator {
v.Check(f >= min, field, v.msg(Min, msg, field, min))

Expand Down
6 changes: 5 additions & 1 deletion notexists.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ const (
NotExistsMsg = "%s already exists"
)

// NotExists checks if given value doesn't exist in desired table or not.
// NotExists checks if the given value doesn't exist in the desired table.
//
// Example:
//
// validator.NotExists(42, "users", "id", "user_id", "user with id 42 already exists.")
func (v *Validator) NotExists(value any, table, column, field, msg string) *Validator {
v.Check(!v.repo.Exists(value, table, column), field, v.msg(NotExists, msg, field))

Expand Down
6 changes: 5 additions & 1 deletion regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ const (
RegexMsg = "%s is not valid"
)

// RegexMatches checks the value of s under validation must match the given regular expression.
// RegexMatches checks if the given value of s under validation matches the given regular expression pattern.
//
// Example:
//
// validator.RegexMatches("example123", "[a-z]+[0-9]+", "input", "input must contain letters followed by numbers.")
func (v *Validator) RegexMatches(s string, pattern string, field, msg string) *Validator {
r := regexp.MustCompile(pattern)

Expand Down
18 changes: 17 additions & 1 deletion required.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,43 @@ const (
)

// RequiredString checks if a string value is empty or not.
//
// Example:
//
// validator.RequiredString("hello", "username", "username is required.")
func (v *Validator) RequiredString(s, field string, msg string) *Validator {
v.Check(strings.TrimSpace(s) != "", field, v.msg(Required, msg, field))

return v
}

// RequiredInt checks if an integer value is provided or not.
//
// Example:
//
// validator.RequiredInt(42, "age", "age is required.")
func (v *Validator) RequiredInt(i int, field string, msg string) *Validator {
v.Check(i != 0, field, v.msg(Required, msg, field))

return v
}

// RequiredSlice checks if a slice has any value or not.
//
// Example:
//
// validator.RequiredSlice([]string{"apple", "banana", "orange"}, "fruits", "at least one fruit must be provided.")
func (v *Validator) RequiredSlice(s []any, field string, msg string) *Validator {
v.Check(len(s) > 0, field, v.msg(Required, msg, field))

return v
}

// RequiredFloat checks if float value is provided or not.
// RequiredFloat checks if a float value is provided or not.
//
// Example:
//
// validator.RequiredFloat(3.5, "weight", "weight is required.")
func (v *Validator) RequiredFloat(f float64, field string, msg string) *Validator {
v.Check(f != 0.0, field, v.msg(Required, msg, field))

Expand Down
6 changes: 6 additions & 0 deletions unqiue.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package validator

// Unique checks whether the values in the provided slice are unique.
//
// Example:
//
// values := []int{1, 2, 3, 4, 5}
// result := Unique(values)
// // result will be true because all values in the slice are unique.
func Unique[T comparable](values []T) bool {
unqiueValues := make(map[T]bool)

Expand Down
10 changes: 7 additions & 3 deletions uuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ const (
UUIDMsg = "%s is not a valid UUID"
)

// UUID The field under validation must be a valid RFC 4122 universally unique identifier (UUID).
// In addition, UUID accepts non-standard strings such as the raw hex encoding xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// and 38 byte "Microsoft style" encodings, e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}.
// UUID validates that the field under validation is a valid RFC 4122 universally unique identifier (UUID).
// It accepts non-standard strings such as raw hex encoding xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// and 38 byte "Microsoft style" encodings, e.g., {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}.
//
// Example:
//
// validator.UUID("f47ac10b-58cc-4372-a567-0e02b2c3d479", "uuid", "Invalid UUID format.")
func (v *Validator) UUID(u, field, msg string) *Validator {
_, err := uuid.Parse(u)
if err != nil {
Expand Down
18 changes: 11 additions & 7 deletions validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,23 @@ func New() *Validator {
return &Validator{}
}

// WithRepo set the desired repository for using in Exists validation rule
// WithRepo sets the desired repository for use in the Exists validation rule.
//
// Example:
//
// validator := New().WithRepo(myRepository)
func (v *Validator) WithRepo(r Repository) *Validator {
v.repo = r

return v
}

// IsPassed checks validator result is passed or not.
// IsPassed checks if the validator result has passed or not.
func (v *Validator) IsPassed() bool {
return len(errs) == 0
}

// IsFailed checks validator result is failed or not.
// IsFailed checks if the validator result has failed or not.
func (v *Validator) IsFailed() bool {
return !v.IsPassed()
}
Expand All @@ -77,23 +81,23 @@ func (v *Validator) Errors() Err {
return vErrs
}

// Check is a dynamic method to define any custom validator rule by passing rule as a func or expression
// Check is a dynamic method to define any custom validator rule by passing a rule as a function or expression
// which will return a boolean.
func (v *Validator) Check(ok bool, field, msg string) {
if !ok {
v.addError(field, msg)
}
}

// addErrors fills errors map and prevent duplicates field from being added to validator errors
// addError fills the errors map and prevents duplicate fields from being added to validator errors.
func (v *Validator) addError(field, msg string) {
if _, exists := errs[field]; !exists {
errs[field] = msg
}
}

// msg return error message and check if custom error message is set return formatted custom message
// otherwise return rule default message
// msg returns the error message. If a custom error message is set, it returns the formatted custom message;
// otherwise, it returns the default message for the rule which has been set on the validator.
func (v *Validator) msg(method, msg string, fieldArgs ...any) string {
if msg != "" {
return msg
Expand Down
6 changes: 6 additions & 0 deletions when.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package validator

// When method will execute the given closure if the given condition is true.
//
// Example:
//
// validator.When(len(username) > 0, func() {
// validator.RequiredString(username, "username", "username is required.")
// })
func (v *Validator) When(condition bool, f func()) *Validator {
if condition {
f()
Expand Down

0 comments on commit c405d16

Please sign in to comment.