Skip to content

Commit 1246622

Browse files
authored
add ISSN validator + tests + documentation (#1166)
## International Standard Serial Number (ISSN) validator "_An ISSN is an 8-digit code used to identify newspapers, journals, magazines and periodicals of all kinds and on all media–print and electronic._" -- [issn.org](https://www.issn.org/understanding-the-issn/what-is-an-issn/) This PR adds a new `issn` validator, along with updating all translation files and tests. This validator is very similar to that of the ISBN so I believe all translations will be okay. The _valid_ ISSNs used in the tests are examples taken from issn.org. **Make sure that you've checked the boxes below before you submit PR:** - [X] Tests exist or have been written that cover this particular change. @go-playground/validator-maintainers
1 parent c856961 commit 1246622

38 files changed

+237
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ validate := validator.New(validator.WithRequiredStructEnabled())
178178
| isbn | International Standard Book Number |
179179
| isbn10 | International Standard Book Number 10 |
180180
| isbn13 | International Standard Book Number 13 |
181+
| issn | International Standard Serial Number |
181182
| iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) |
182183
| iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) |
183184
| iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) |

baked_in.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ var (
150150
"isbn": isISBN,
151151
"isbn10": isISBN10,
152152
"isbn13": isISBN13,
153+
"issn": isISSN,
153154
"eth_addr": isEthereumAddress,
154155
"eth_addr_checksum": isEthereumAddressChecksum,
155156
"btc_addr": isBitcoinAddress,
@@ -651,6 +652,32 @@ func isISBN10(fl FieldLevel) bool {
651652
return checksum%11 == 0
652653
}
653654

655+
// isISSN is the validation function for validating if the field's value is a valid ISSN.
656+
func isISSN(fl FieldLevel) bool {
657+
s := fl.Field().String()
658+
659+
if !iSSNRegex.MatchString(s) {
660+
return false
661+
}
662+
s = strings.ReplaceAll(s, "-", "")
663+
664+
pos := 8
665+
checksum := 0
666+
667+
for i := 0; i < 7; i++ {
668+
checksum += pos * int(s[i]-'0')
669+
pos--
670+
}
671+
672+
if s[7] == 'X' {
673+
checksum += 10
674+
} else {
675+
checksum += int(s[7] - '0')
676+
}
677+
678+
return checksum%11 == 0
679+
}
680+
654681
// isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address.
655682
func isEthereumAddress(fl FieldLevel) bool {
656683
address := fl.Field().String()

regexes.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const (
2222
base64RawURLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2,4})$"
2323
iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
2424
iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
25+
iSSNRegexString = "^(?:[0-9]{4}-[0-9]{3}[0-9X])$"
2526
uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
2627
uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
2728
uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
@@ -93,6 +94,7 @@ var (
9394
base64RawURLRegex = regexp.MustCompile(base64RawURLRegexString)
9495
iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
9596
iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
97+
iSSNRegex = regexp.MustCompile(iSSNRegexString)
9698
uUID3Regex = regexp.MustCompile(uUID3RegexString)
9799
uUID4Regex = regexp.MustCompile(uUID4RegexString)
98100
uUID5Regex = regexp.MustCompile(uUID5RegexString)

translations/ar/ar.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11161116
translation: "يجب أن يكون {0} رقم ISBN-13 صالح",
11171117
override: false,
11181118
},
1119+
{
1120+
tag: "issn",
1121+
translation: "يجب أن يكون {0} رقم ISSN صالح",
1122+
override: false,
1123+
},
11191124
{
11201125
tag: "uuid",
11211126
translation: "يجب أن يكون {0} UUID صالح",

translations/ar/ar_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ func TestTranslations(t *testing.T) {
9999
ISBN string `validate:"isbn"`
100100
ISBN10 string `validate:"isbn10"`
101101
ISBN13 string `validate:"isbn13"`
102+
ISSN string `validate:"issn"`
102103
UUID string `validate:"uuid"`
103104
UUID3 string `validate:"uuid3"`
104105
UUID4 string `validate:"uuid4"`
@@ -341,6 +342,10 @@ func TestTranslations(t *testing.T) {
341342
ns: "Test.ISBN13",
342343
expected: "يجب أن يكون ISBN13 رقم ISBN-13 صالح",
343344
},
345+
{
346+
ns: "Test.ISSN",
347+
expected: "يجب أن يكون ISSN رقم ISSN صالح",
348+
},
344349
{
345350
ns: "Test.Excludes",
346351
expected: "لا يمكن أن يحتوي Excludes على النص 'text'",

translations/en/en.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/go-playground/locales"
1212
ut "github.com/go-playground/universal-translator"
13+
1314
"github.com/go-playground/validator/v10"
1415
)
1516

@@ -1121,6 +1122,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11211122
translation: "{0} must be a valid ISBN-13 number",
11221123
override: false,
11231124
},
1125+
{
1126+
tag: "issn",
1127+
translation: "{0} must be a valid ISSN number",
1128+
override: false,
1129+
},
11241130
{
11251131
tag: "uuid",
11261132
translation: "{0} must be a valid UUID",

translations/en/en_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ func TestTranslations(t *testing.T) {
101101
ISBN string `validate:"isbn"`
102102
ISBN10 string `validate:"isbn10"`
103103
ISBN13 string `validate:"isbn13"`
104+
ISSN string `validate:"issn"`
104105
UUID string `validate:"uuid"`
105106
UUID3 string `validate:"uuid3"`
106107
UUID4 string `validate:"uuid4"`
@@ -354,6 +355,10 @@ func TestTranslations(t *testing.T) {
354355
ns: "Test.ISBN13",
355356
expected: "ISBN13 must be a valid ISBN-13 number",
356357
},
358+
{
359+
ns: "Test.ISSN",
360+
expected: "ISSN must be a valid ISSN number",
361+
},
357362
{
358363
ns: "Test.Excludes",
359364
expected: "Excludes cannot contain the text 'text'",

translations/es/es.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11631163
translation: "{0} debe ser un número ISBN-13 válido",
11641164
override: false,
11651165
},
1166+
{
1167+
tag: "issn",
1168+
translation: "{0} debe ser un número ISSN válido",
1169+
override: false,
1170+
},
11661171
{
11671172
tag: "uuid",
11681173
translation: "{0} debe ser un UUID válido",

translations/es/es_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ func TestTranslations(t *testing.T) {
101101
ISBN string `validate:"isbn"`
102102
ISBN10 string `validate:"isbn10"`
103103
ISBN13 string `validate:"isbn13"`
104+
ISSN string `validate:"issn"`
104105
UUID string `validate:"uuid"`
105106
UUID3 string `validate:"uuid3"`
106107
UUID4 string `validate:"uuid4"`
@@ -331,6 +332,10 @@ func TestTranslations(t *testing.T) {
331332
ns: "Test.ISBN13",
332333
expected: "ISBN13 debe ser un número ISBN-13 válido",
333334
},
335+
{
336+
ns: "Test.ISSN",
337+
expected: "ISSN debe ser un número ISSN válido",
338+
},
334339
{
335340
ns: "Test.Excludes",
336341
expected: "Excludes no puede contener el texto 'text'",

translations/fa/fa.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11161116
translation: "{0} باید یک شابک(ISBN-13) معتبر باشد",
11171117
override: false,
11181118
},
1119+
{
1120+
tag: "issn",
1121+
translation: "{0} باید یک شابک(ISSN) معتبر باشد",
1122+
override: false,
1123+
},
11191124
{
11201125
tag: "uuid",
11211126
translation: "{0} باید یک UUID معتبر باشد",

0 commit comments

Comments
 (0)