Golang client can use pattern-based discriminator between oneOf (#18760)

* Enable reading schemas with pattern-based discriminator between oneOf for golang client #5311

* Codegen after changing to golang templates #5311
This commit is contained in:
Max Lapshin 2024-06-13 11:31:36 +03:00 committed by GitHub
parent 26a164e57f
commit 788fd6f725
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 162 additions and 32 deletions

View File

@ -724,6 +724,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
for (ModelMap m : objs.getModels()) {
boolean addedTimeImport = false;
boolean addedOSImport = false;
boolean addedValidator = false;
CodegenModel model = m.getModel();
List<CodegenProperty> inheritedProperties = new ArrayList<>();
@ -758,11 +759,22 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
if (cp.pattern != null) {
cp.vendorExtensions.put("x-go-custom-tag", "validate:\"regexp=" +
cp.pattern.replace("\\","\\\\").replaceAll("^/|/$","") +
"\"");
}
}
if (this instanceof GoClientCodegen && model.isEnum) {
imports.add(createMapping("import", "fmt"));
}
if(model.oneOf != null && !model.oneOf.isEmpty() && !addedValidator && generateUnmarshalJSON) {
imports.add(createMapping("import", "gopkg.in/validator.v2"));
addedValidator = true;
}
// if oneOf contains "null" type
if (model.oneOf != null && !model.oneOf.isEmpty() && model.oneOf.contains("nil")) {
model.isNullable = true;

View File

@ -93,7 +93,11 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error {
if string(json{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) == "{}" { // empty struct
dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil
} else {
match++
if err = validator.Validate(dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}); err != nil {
dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil
} else {
match++
}
}
} else {
dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil

View File

@ -20,7 +20,7 @@ type {{classname}} struct {
{{#deprecated}}
// Deprecated
{{/deprecated}}
{{name}} {{^required}}{{^isNullable}}{{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{/isNullable}}{{/required}}{{{dataType}}} `json:"{{{baseName}}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{{baseName}}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{name}} {{^required}}{{^isNullable}}{{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{/isNullable}}{{/required}}{{{dataType}}} `json:"{{{baseName}}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{{baseName}}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#withValidate}} validate:"{{validate}}"{{/withValidate}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{/vars}}
{{#isAdditionalPropertiesTrue}}
AdditionalProperties map[string]interface{}

View File

@ -0,0 +1,26 @@
openapi: 3.0.0
info:
title: Test
version: 1.0.0
paths: {}
components:
schemas:
rtmp_source:
required:
- url
properties:
url:
type: string
pattern: "^rtmp://.+$"
hls_source:
required:
- url
properties:
url:
type: string
description: this pattern is more complicated and requires escaping
pattern: "^hls://.+$|^http.*\\.m3u8$"
source:
oneOf:
- $ref: '#/components/schemas/rtmp_source'
- $ref: '#/components/schemas/hls_source'

View File

@ -12,6 +12,7 @@ package openapi
import (
"encoding/json"
"gopkg.in/validator.v2"
"fmt"
)
@ -47,7 +48,11 @@ func (dst *Object) UnmarshalJSON(data []byte) error {
if string(jsonNestedObject1) == "{}" { // empty struct
dst.NestedObject1 = nil
} else {
match++
if err = validator.Validate(dst.NestedObject1); err != nil {
dst.NestedObject1 = nil
} else {
match++
}
}
} else {
dst.NestedObject1 = nil
@ -60,7 +65,11 @@ func (dst *Object) UnmarshalJSON(data []byte) error {
if string(jsonNestedObject2) == "{}" { // empty struct
dst.NestedObject2 = nil
} else {
match++
if err = validator.Validate(dst.NestedObject2); err != nil {
dst.NestedObject2 = nil
} else {
match++
}
}
} else {
dst.NestedObject2 = nil

View File

@ -29,8 +29,8 @@ type FormatTest struct {
Number float32 `json:"number"`
Float *float32 `json:"float,omitempty"`
Double *float64 `json:"double,omitempty"`
String *string `json:"string,omitempty"`
Byte string `json:"byte"`
String *string `json:"string,omitempty" validate:"regexp=[a-z]/i"`
Byte string `json:"byte" validate:"regexp=^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=)?$"`
Binary **os.File `json:"binary,omitempty"`
Date string `json:"date"`
DateTime *time.Time `json:"dateTime,omitempty"`

View File

@ -20,7 +20,7 @@ var _ MappedNullable = &Category{}
// Category A category for a pet
type Category struct {
Id *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Name *string `json:"name,omitempty" validate:"regexp=^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$"`
AdditionalProperties map[string]interface{}
}

View File

@ -28,7 +28,7 @@ type FormatTest struct {
Number float32 `json:"number"`
Float *float32 `json:"float,omitempty"`
Double *float64 `json:"double,omitempty"`
String *string `json:"string,omitempty"`
String *string `json:"string,omitempty" validate:"regexp=[a-z]/i"`
Byte string `json:"byte"`
Binary **os.File `json:"binary,omitempty"`
Date string `json:"date"`
@ -36,9 +36,9 @@ type FormatTest struct {
Uuid *string `json:"uuid,omitempty"`
Password string `json:"password"`
// A string that is a 10 digit number. Can have leading zeros.
PatternWithDigits *string `json:"pattern_with_digits,omitempty"`
PatternWithDigits *string `json:"pattern_with_digits,omitempty" validate:"regexp=^\\\\d{10}$"`
// A string starting with 'image_' (case insensitive) and one to three digits following i.e. Image_01.
PatternWithDigitsAndDelimiter *string `json:"pattern_with_digits_and_delimiter,omitempty"`
PatternWithDigitsAndDelimiter *string `json:"pattern_with_digits_and_delimiter,omitempty" validate:"regexp=^image_\\\\d{1,3}$/i"`
AdditionalProperties map[string]interface{}
}

View File

@ -12,6 +12,7 @@ package petstore
import (
"encoding/json"
"gopkg.in/validator.v2"
"fmt"
)
@ -47,7 +48,11 @@ func (dst *Fruit) UnmarshalJSON(data []byte) error {
if string(jsonApple) == "{}" { // empty struct
dst.Apple = nil
} else {
match++
if err = validator.Validate(dst.Apple); err != nil {
dst.Apple = nil
} else {
match++
}
}
} else {
dst.Apple = nil
@ -60,7 +65,11 @@ func (dst *Fruit) UnmarshalJSON(data []byte) error {
if string(jsonBanana) == "{}" { // empty struct
dst.Banana = nil
} else {
match++
if err = validator.Validate(dst.Banana); err != nil {
dst.Banana = nil
} else {
match++
}
}
} else {
dst.Banana = nil

View File

@ -12,6 +12,7 @@ package petstore
import (
"encoding/json"
"gopkg.in/validator.v2"
"fmt"
)
@ -47,7 +48,11 @@ func (dst *FruitReq) UnmarshalJSON(data []byte) error {
if string(jsonAppleReq) == "{}" { // empty struct
dst.AppleReq = nil
} else {
match++
if err = validator.Validate(dst.AppleReq); err != nil {
dst.AppleReq = nil
} else {
match++
}
}
} else {
dst.AppleReq = nil
@ -60,7 +65,11 @@ func (dst *FruitReq) UnmarshalJSON(data []byte) error {
if string(jsonBananaReq) == "{}" { // empty struct
dst.BananaReq = nil
} else {
match++
if err = validator.Validate(dst.BananaReq); err != nil {
dst.BananaReq = nil
} else {
match++
}
}
} else {
dst.BananaReq = nil

View File

@ -12,6 +12,7 @@ package petstore
import (
"encoding/json"
"gopkg.in/validator.v2"
"fmt"
)
@ -52,7 +53,11 @@ func (dst *IncidentData) UnmarshalJSON(data []byte) error {
if string(jsonArrayOfMapmapOfStringAny) == "{}" { // empty struct
dst.ArrayOfMapmapOfStringAny = nil
} else {
match++
if err = validator.Validate(dst.ArrayOfMapmapOfStringAny); err != nil {
dst.ArrayOfMapmapOfStringAny = nil
} else {
match++
}
}
} else {
dst.ArrayOfMapmapOfStringAny = nil
@ -65,7 +70,11 @@ func (dst *IncidentData) UnmarshalJSON(data []byte) error {
if string(jsonMapmapOfStringAny) == "{}" { // empty struct
dst.MapmapOfStringAny = nil
} else {
match++
if err = validator.Validate(dst.MapmapOfStringAny); err != nil {
dst.MapmapOfStringAny = nil
} else {
match++
}
}
} else {
dst.MapmapOfStringAny = nil

View File

@ -12,6 +12,7 @@ package petstore
import (
"encoding/json"
"gopkg.in/validator.v2"
"fmt"
)
@ -47,7 +48,11 @@ func (dst *Mammal) UnmarshalJSON(data []byte) error {
if string(jsonWhale) == "{}" { // empty struct
dst.Whale = nil
} else {
match++
if err = validator.Validate(dst.Whale); err != nil {
dst.Whale = nil
} else {
match++
}
}
} else {
dst.Whale = nil
@ -60,7 +65,11 @@ func (dst *Mammal) UnmarshalJSON(data []byte) error {
if string(jsonZebra) == "{}" { // empty struct
dst.Zebra = nil
} else {
match++
if err = validator.Validate(dst.Zebra); err != nil {
dst.Zebra = nil
} else {
match++
}
}
} else {
dst.Zebra = nil

View File

@ -12,6 +12,7 @@ package petstore
import (
"encoding/json"
"gopkg.in/validator.v2"
"fmt"
)
@ -55,7 +56,11 @@ func (dst *OneOfPrimitiveType) UnmarshalJSON(data []byte) error {
if string(jsonOneOfPrimitiveTypeChild) == "{}" { // empty struct
dst.OneOfPrimitiveTypeChild = nil
} else {
match++
if err = validator.Validate(dst.OneOfPrimitiveTypeChild); err != nil {
dst.OneOfPrimitiveTypeChild = nil
} else {
match++
}
}
} else {
dst.OneOfPrimitiveTypeChild = nil
@ -68,7 +73,11 @@ func (dst *OneOfPrimitiveType) UnmarshalJSON(data []byte) error {
if string(jsonArrayOfString) == "{}" { // empty struct
dst.ArrayOfString = nil
} else {
match++
if err = validator.Validate(dst.ArrayOfString); err != nil {
dst.ArrayOfString = nil
} else {
match++
}
}
} else {
dst.ArrayOfString = nil
@ -81,7 +90,11 @@ func (dst *OneOfPrimitiveType) UnmarshalJSON(data []byte) error {
if string(jsonInt32) == "{}" { // empty struct
dst.Int32 = nil
} else {
match++
if err = validator.Validate(dst.Int32); err != nil {
dst.Int32 = nil
} else {
match++
}
}
} else {
dst.Int32 = nil

View File

@ -13,6 +13,7 @@ package petstore
import (
"encoding/json"
"time"
"gopkg.in/validator.v2"
"fmt"
)
@ -48,7 +49,11 @@ func (dst *OneOfPrimitiveTypes) UnmarshalJSON(data []byte) error {
if string(jsonString) == "{}" { // empty struct
dst.String = nil
} else {
match++
if err = validator.Validate(dst.String); err != nil {
dst.String = nil
} else {
match++
}
}
} else {
dst.String = nil
@ -61,7 +66,11 @@ func (dst *OneOfPrimitiveTypes) UnmarshalJSON(data []byte) error {
if string(jsonTimeTime) == "{}" { // empty struct
dst.TimeTime = nil
} else {
match++
if err = validator.Validate(dst.TimeTime); err != nil {
dst.TimeTime = nil
} else {
match++
}
}
} else {
dst.TimeTime = nil

View File

@ -5,8 +5,11 @@ go 1.16
replace go-petstore => ./go-petstore
require (
github.com/stretchr/testify v1.8.4
cloud.google.com/go/compute v1.20.1 // indirect
github.com/stretchr/testify v1.9.0
go-petstore v0.0.0-00010101000000-000000000000
golang.org/x/net v0.20.0 // indirect
golang.org/x/oauth2 v0.16.0
golang.org/x/net v0.25.0 // indirect
golang.org/x/oauth2 v0.20.0
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/validator.v2 v2.0.1 // indirect
)

View File

@ -178,6 +178,7 @@ cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZ
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=
cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=
@ -841,6 +842,7 @@ github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcD
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
@ -854,6 +856,8 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -889,6 +893,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1022,6 +1028,9 @@ golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1065,6 +1074,8 @@ golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1163,6 +1174,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -1175,6 +1188,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1193,6 +1208,7 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1559,6 +1575,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/validator.v2 v2.0.1 h1:xF0KWyGWXm/LM2G1TrEjqOu4pa6coO9AlWSf3msVfDY=
gopkg.in/validator.v2 v2.0.1/go.mod h1:lIUZBlB3Im4s/eYp39Ry/wkR02yOPhZ9IwIRBjuPuG8=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=

View File

@ -18,7 +18,7 @@ type Category struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Name string `json:"name,omitempty" validate:"regexp=^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$"`
}
// AssertCategoryRequired checks if the required fields are not zero-ed

View File

@ -18,7 +18,7 @@ type Category struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Name string `json:"name,omitempty" validate:"regexp=^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$"`
}
// AssertCategoryRequired checks if the required fields are not zero-ed

View File

@ -18,7 +18,7 @@ type Category struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Name string `json:"name,omitempty" validate:"regexp=^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$"`
}
// AssertCategoryRequired checks if the required fields are not zero-ed

View File

@ -5,5 +5,5 @@ type Category struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Name string `json:"name,omitempty" validate:"regexp=^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$"`
}

View File

@ -14,5 +14,5 @@ type Category struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Name string `json:"name,omitempty" validate:"regexp=^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$"`
}

View File

@ -14,5 +14,5 @@ type Category struct {
Id int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Name string `json:"name,omitempty" validate:"regexp=^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$"`
}