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

+1
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

+27
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

+2
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

+5
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

+5
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

+6
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

+5
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

+5
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

+5
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

+5
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/fa/fa_test.go

+5
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"`
@@ -340,6 +341,10 @@ func TestTranslations(t *testing.T) {
340341
ns: "Test.ISBN13",
341342
expected: "ISBN13 باید یک شابک(ISBN-13) معتبر باشد",
342343
},
344+
{
345+
ns: "Test.ISSN",
346+
expected: "ISSN باید یک شابک(ISSN) معتبر باشد",
347+
},
343348
{
344349
ns: "Test.Excludes",
345350
expected: "Excludes نمیتواند شامل 'text' باشد",

translations/fr/fr.go

+5
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11531153
translation: "{0} doit être un numéro ISBN-13 valid",
11541154
override: false,
11551155
},
1156+
{
1157+
tag: "issn",
1158+
translation: "{0} doit être un numéro ISSN valid",
1159+
override: false,
1160+
},
11561161
{
11571162
tag: "uuid",
11581163
translation: "{0} doit être un UUID valid",

translations/fr/fr_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func TestTranslations(t *testing.T) {
100100
ISBN string `validate:"isbn"`
101101
ISBN10 string `validate:"isbn10"`
102102
ISBN13 string `validate:"isbn13"`
103+
ISSN string `validate:"issn"`
103104
UUID string `validate:"uuid"`
104105
UUID3 string `validate:"uuid3"`
105106
UUID4 string `validate:"uuid4"`
@@ -324,6 +325,10 @@ func TestTranslations(t *testing.T) {
324325
ns: "Test.ISBN13",
325326
expected: "ISBN13 doit être un numéro ISBN-13 valid",
326327
},
328+
{
329+
ns: "Test.ISSN",
330+
expected: "ISSN doit être un numéro ISSN valid",
331+
},
327332
{
328333
ns: "Test.Excludes",
329334
expected: "Excludes ne doit pas contenir le texte 'text'",

translations/id/id.go

+5
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11531153
translation: "{0} harus berupa nomor ISBN-13 yang valid",
11541154
override: false,
11551155
},
1156+
{
1157+
tag: "issn",
1158+
translation: "{0} harus berupa nomor ISSN yang valid",
1159+
override: false,
1160+
},
11561161
{
11571162
tag: "uuid",
11581163
translation: "{0} harus berupa UUID yang valid",

translations/id/id_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func TestTranslations(t *testing.T) {
100100
ISBN string `validate:"isbn"`
101101
ISBN10 string `validate:"isbn10"`
102102
ISBN13 string `validate:"isbn13"`
103+
ISSN string `validate:"issn"`
103104
UUID string `validate:"uuid"`
104105
UUID3 string `validate:"uuid3"`
105106
UUID4 string `validate:"uuid4"`
@@ -324,6 +325,10 @@ func TestTranslations(t *testing.T) {
324325
ns: "Test.ISBN13",
325326
expected: "ISBN13 harus berupa nomor ISBN-13 yang valid",
326327
},
328+
{
329+
ns: "Test.ISSN",
330+
expected: "ISSN harus berupa nomor ISSN yang valid",
331+
},
327332
{
328333
ns: "Test.Excludes",
329334
expected: "Excludes tidak boleh berisi teks 'text'",

translations/it/it.go

+5
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
977977
translation: "{0} deve essere un numero ISBN-13 valido",
978978
override: false,
979979
},
980+
{
981+
tag: "issn",
982+
translation: "{0} deve essere un numero ISSN valido",
983+
override: false,
984+
},
980985
{
981986
tag: "uuid",
982987
translation: "{0} deve essere un UUID valido",

translations/it/it_test.go

+5
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"`
@@ -351,6 +352,10 @@ func TestTranslations(t *testing.T) {
351352
ns: "Test.ISBN13",
352353
expected: "ISBN13 deve essere un numero ISBN-13 valido",
353354
},
355+
{
356+
ns: "Test.ISSN",
357+
expected: "ISSN deve essere un numero ISSN valido",
358+
},
354359
{
355360
ns: "Test.Excludes",
356361
expected: "Excludes non deve contenere il testo 'text'",

translations/ja/ja.go

+5
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11861186
translation: "{0}は正しいISBN-13番号でなければなりません",
11871187
override: false,
11881188
},
1189+
{
1190+
tag: "issn",
1191+
translation: "{0}は正しいISSN番号でなければなりません",
1192+
override: false,
1193+
},
11891194
{
11901195
tag: "uuid",
11911196
translation: "{0}は正しいUUIDでなければなりません",

translations/ja/ja_test.go

+5
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"`
@@ -347,6 +348,10 @@ func TestTranslations(t *testing.T) {
347348
ns: "Test.ISBN13",
348349
expected: "ISBN13は正しいISBN-13番号でなければなりません",
349350
},
351+
{
352+
ns: "Test.ISSN",
353+
expected: "ISSNは正しいISSN番号でなければなりません",
354+
},
350355
{
351356
ns: "Test.Excludes",
352357
expected: "Excludesには'text'というテキストを含むことはできません",

translations/lv/lv.go

+5
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11211121
translation: "{0} jābūt derīgam ISBN-13 numuram",
11221122
override: false,
11231123
},
1124+
{
1125+
tag: "issn",
1126+
translation: "{0} jābūt derīgam ISSN numuram",
1127+
override: false,
1128+
},
11241129
{
11251130
tag: "uuid",
11261131
translation: "{0} jābūt derīgam UUID",

translations/lv/lv_test.go

+5
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"`
@@ -346,6 +347,10 @@ func TestTranslations(t *testing.T) {
346347
ns: "Test.ISBN13",
347348
expected: "ISBN13 jābūt derīgam ISBN-13 numuram",
348349
},
350+
{
351+
ns: "Test.ISSN",
352+
expected: "ISSN jābūt derīgam ISSN numuram",
353+
},
349354
{
350355
ns: "Test.Excludes",
351356
expected: "Excludes nedrīkst saturēt tekstu 'text'",

translations/nl/nl.go

+5
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11531153
translation: "{0} moet een geldig ISBN-13 nummer zijn",
11541154
override: false,
11551155
},
1156+
{
1157+
tag: "issn",
1158+
translation: "{0} moet een geldig ISSN nummer zijn",
1159+
override: false,
1160+
},
11561161
{
11571162
tag: "uuid",
11581163
translation: "{0} moet een geldige UUID zijn",

translations/nl/nl_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func TestTranslations(t *testing.T) {
100100
ISBN string `validate:"isbn"`
101101
ISBN10 string `validate:"isbn10"`
102102
ISBN13 string `validate:"isbn13"`
103+
ISSN string `validate:"issn"`
103104
UUID string `validate:"uuid"`
104105
UUID3 string `validate:"uuid3"`
105106
UUID4 string `validate:"uuid4"`
@@ -324,6 +325,10 @@ func TestTranslations(t *testing.T) {
324325
ns: "Test.ISBN13",
325326
expected: "ISBN13 moet een geldig ISBN-13 nummer zijn",
326327
},
328+
{
329+
ns: "Test.ISSN",
330+
expected: "ISSN moet een geldig ISSN nummer zijn",
331+
},
327332
{
328333
ns: "Test.Excludes",
329334
expected: "Excludes mag niet de tekst 'text' bevatten",

translations/pt/pt.go

+5
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
11581158
translation: "{0} deve ser um número ISBN-13 válido",
11591159
override: false,
11601160
},
1161+
{
1162+
tag: "issn",
1163+
translation: "{0} deve ser um número ISSN válido",
1164+
override: false,
1165+
},
11611166
{
11621167
tag: "uuid",
11631168
translation: "{0} deve ser um UUID válido",

0 commit comments

Comments
 (0)