Skip to content

Commit d2ed55d

Browse files
authored
Merge branch 'master' into master
2 parents bab11f0 + 8592022 commit d2ed55d

File tree

29 files changed

+9688
-1724
lines changed

29 files changed

+9688
-1724
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Bug Report
2+
description: File a bug report
3+
title: "[Bug]: "
4+
labels: ["bug"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
Thanks for taking the time to fill out this bug report!
10+
- type: textarea
11+
id: what-happened
12+
attributes:
13+
label: What happened?
14+
description: Also tell us, what did you expect to happen?
15+
validations:
16+
required: true
17+
- type: textarea
18+
id: version
19+
attributes:
20+
label: Version
21+
description: What version of validator are you running?
22+
validations:
23+
required: true
24+
- type: textarea
25+
id: code
26+
attributes:
27+
label: Example Code
28+
description: Please provide a code example that demonstrates the issue
29+
render: go
30+
validations:
31+
required: true

.github/dependabot.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: 2
2+
updates:
3+
# Maintain dependencies for Golang
4+
- package-ecosystem: gomod
5+
directory: "/"
6+
schedule:
7+
interval: weekly
8+
# Maintain dependencies for GitHub Actions
9+
- package-ecosystem: github-actions
10+
directory: "/"
11+
schedule:
12+
interval: weekly

.github/workflows/workflow.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
test:
99
strategy:
1010
matrix:
11-
go-version: [1.20.x,1.21.x,1.22.x,1.23.x]
11+
go-version: [1.22.x,1.23.x, 1.24.x]
1212
os: [ubuntu-latest, macos-latest, windows-latest]
1313
runs-on: ${{ matrix.os }}
1414
steps:
@@ -24,7 +24,7 @@ jobs:
2424
run: go test -race -covermode=atomic -coverprofile="profile.cov" ./...
2525

2626
- name: Send Coverage
27-
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.22.x'
27+
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.23.x'
2828
uses: shogo82148/actions-goveralls@v1
2929
with:
3030
path-to-profile: profile.cov
@@ -36,8 +36,8 @@ jobs:
3636
- uses: actions/checkout@v4
3737
- uses: actions/setup-go@v5
3838
with:
39-
go-version: 1.23.x
39+
go-version: 1.24.x
4040
- name: golangci-lint
41-
uses: golangci/golangci-lint-action@v4
41+
uses: golangci/golangci-lint-action@v6
4242
with:
4343
version: latest

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
Package validator
22
=================
3-
<img align="right" src="logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4-
![Project status](https://img.shields.io/badge/version-10.24.0-green.svg)
3+
<img align="right" src="logo.png">![Project status](https://img.shields.io/badge/version-10.25.0-green.svg)
54
[![Build Status](https://github.com/go-playground/validator/actions/workflows/workflow.yml/badge.svg)](https://github.com/go-playground/validator/actions)
65
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
76
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
@@ -173,6 +172,7 @@ validate := validator.New(validator.WithRequiredStructEnabled())
173172
| spicedb | SpiceDb ObjectID/Permission/Type |
174173
| datetime | Datetime |
175174
| e164 | e164 formatted phone number |
175+
| ein | U.S. Employeer Identification Number |
176176
| email | E-mail String
177177
| eth_addr | Ethereum Address |
178178
| hexadecimal | Hexadecimal String |

_examples/simple/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ func validateStruct() {
6262
// this check is only needed when your code could produce
6363
// an invalid value for validation such as interface with nil
6464
// value most including myself do not usually have code like this.
65-
if errors.As(err, &validator.InvalidValidationError{}) {
65+
var invalidValidationError *validator.InvalidValidationError
66+
if errors.As(err, &invalidValidationError) {
6667
fmt.Println(err)
6768
return
6869
}

_examples/struct-level/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ func main() {
115115
// this check is only needed when your code could produce
116116
// an invalid value for validation such as interface with nil
117117
// value most including myself do not usually have code like this.
118-
if errors.As(err, &validator.InvalidValidationError{}) {
118+
var invalidValidationError *validator.InvalidValidationError
119+
if errors.As(err, &invalidValidationError) {
119120
fmt.Println(err)
120121
return
121122
}

baked_in.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"fmt"
1010
"io/fs"
1111
"net"
12+
"net/mail"
1213
"net/url"
1314
"os"
1415
"reflect"
@@ -50,6 +51,7 @@ var (
5051
keysTag: {},
5152
endKeysTag: {},
5253
structOnlyTag: {},
54+
omitzero: {},
5355
omitempty: {},
5456
omitnil: {},
5557
skipValidationTag: {},
@@ -242,6 +244,7 @@ var (
242244
"cron": isCron,
243245
"spicedb": isSpiceDB,
244246
"oci_tag": isOciTag,
247+
"ein": isEIN,
245248
}
246249
)
247250

@@ -1376,7 +1379,6 @@ func isEqIgnoreCase(fl FieldLevel) bool {
13761379
param := fl.Param()
13771380

13781381
switch field.Kind() {
1379-
13801382
case reflect.String:
13811383
return strings.EqualFold(field.String(), param)
13821384
}
@@ -1606,7 +1608,6 @@ func isImage(fl FieldLevel) bool {
16061608
case reflect.String:
16071609
filePath := field.String()
16081610
fileInfo, err := os.Stat(filePath)
1609-
16101611
if err != nil {
16111612
return false
16121613
}
@@ -1635,7 +1636,6 @@ func isImage(fl FieldLevel) bool {
16351636

16361637
// isFilePath is the validation function for validating if the current field's value is a valid file path.
16371638
func isFilePath(fl FieldLevel) bool {
1638-
16391639
var exists bool
16401640
var err error
16411641

@@ -1695,6 +1695,10 @@ func isE164(fl FieldLevel) bool {
16951695

16961696
// isEmail is the validation function for validating if the current field's value is a valid email address.
16971697
func isEmail(fl FieldLevel) bool {
1698+
_, err := mail.ParseAddress(fl.Field().String())
1699+
if err != nil {
1700+
return false
1701+
}
16981702
return emailRegex().MatchString(fl.Field().String())
16991703
}
17001704

@@ -1798,6 +1802,20 @@ func hasValue(fl FieldLevel) bool {
17981802
}
17991803
}
18001804

1805+
// hasNotZeroValue is the validation function for validating if the current field's value is not the zero value for its type.
1806+
func hasNotZeroValue(fl FieldLevel) bool {
1807+
field := fl.Field()
1808+
switch field.Kind() {
1809+
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
1810+
return !field.IsNil()
1811+
default:
1812+
if fl.(*validate).fldIsPointer && field.Interface() != nil {
1813+
return !field.IsZero()
1814+
}
1815+
return field.IsValid() && !field.IsZero()
1816+
}
1817+
}
1818+
18011819
// requireCheckFieldKind is a func for check field kind
18021820
func requireCheckFieldKind(fl FieldLevel, param string, defaultNotFoundValue bool) bool {
18031821
field := fl.Field()
@@ -2213,7 +2231,6 @@ func isGt(fl FieldLevel) bool {
22132231
case reflect.Struct:
22142232

22152233
if field.Type().ConvertibleTo(timeType) {
2216-
22172234
return field.Convert(timeType).Interface().(time.Time).After(time.Now().UTC())
22182235
}
22192236
}
@@ -2450,7 +2467,6 @@ func isLt(fl FieldLevel) bool {
24502467
case reflect.Struct:
24512468

24522469
if field.Type().ConvertibleTo(timeType) {
2453-
24542470
return field.Convert(timeType).Interface().(time.Time).Before(time.Now().UTC())
24552471
}
24562472
}
@@ -2630,7 +2646,6 @@ func isDir(fl FieldLevel) bool {
26302646

26312647
// isDirPath is the validation function for validating if the current field's value is a valid directory.
26322648
func isDirPath(fl FieldLevel) bool {
2633-
26342649
var exists bool
26352650
var err error
26362651

@@ -2943,6 +2958,12 @@ func isCveFormat(fl FieldLevel) bool {
29432958
// a valid dns RFC 1035 label, defined in RFC 1035.
29442959
func isDnsRFC1035LabelFormat(fl FieldLevel) bool {
29452960
val := fl.Field().String()
2961+
2962+
size := len(val)
2963+
if size > 63 {
2964+
return false
2965+
}
2966+
29462967
return dnsRegexRFC1035Label().MatchString(val)
29472968
}
29482969

@@ -3050,4 +3071,14 @@ func isCron(fl FieldLevel) bool {
30503071
// isOciTag is the validation function for validating if the current field's value is a valid OCI tag, as described in the OCI Distribution Specification: https://github.com/opencontainers/distribution-spec/blob/main/spec.md
30513072
func isOciTag(fl FieldLevel) bool {
30523073
return ociTagRegex().MatchString(fl.Field().String())
3074+
3075+
// isEIN is the validation function for validating if the current field's value is a valid U.S. Employer Identification Number (EIN)
3076+
func isEIN(fl FieldLevel) bool {
3077+
field := fl.Field()
3078+
3079+
if field.Len() != 10 {
3080+
return false
3081+
}
3082+
3083+
return einRegex().MatchString(field.String())
30533084
}

cache.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const (
2121
typeKeys
2222
typeEndKeys
2323
typeOmitNil
24+
typeOmitZero
2425
)
2526

2627
const (
@@ -249,6 +250,10 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s
249250
}
250251
return
251252

253+
case omitzero:
254+
current.typeof = typeOmitZero
255+
continue
256+
252257
case omitempty:
253258
current.typeof = typeOmitEmpty
254259
continue

doc.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ Although an empty string is a valid base64 URL safe value, this will report
959959
an empty string as an error, if you wish to accept an empty string as valid
960960
you can use this with the omitempty tag.
961961
962-
Usage: base64url
962+
Usage: base64rawurl
963963
964964
# Bitcoin Address
965965
@@ -1134,6 +1134,12 @@ This validates that a string value contains a valid longitude.
11341134
11351135
Usage: longitude
11361136
1137+
# Employeer Identification Number EIN
1138+
1139+
This validates that a string value contains a valid U.S. Employer Identification Number.
1140+
1141+
Usage: ein
1142+
11371143
# Social Security Number SSN
11381144
11391145
This validates that a string value contains a valid U.S. Social Security Number.

0 commit comments

Comments
 (0)