mirror of
https://gitee.com/johng/gf.git
synced 2024-11-29 18:57:44 +08:00
move common used tag from packages to package gtag for maintainability (#2256)
* move common used tag from packages to package gtag for maintainability * move common used tag from packages to package gtag for maintainability Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
parent
033ba588c9
commit
ee58255418
@ -25,6 +25,7 @@ import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
"github.com/gogf/gf/v2/util/gutil"
|
||||
"github.com/google/uuid"
|
||||
"github.com/shopspring/decimal"
|
||||
@ -49,7 +50,7 @@ const (
|
||||
filterTypePattern = `(?i)^UPDATE|DELETE`
|
||||
replaceSchemaPattern = `@(.+?)/([\w\.\-]+)+`
|
||||
needParsedSqlInCtx gctx.StrKey = "NeedParsedSql"
|
||||
OrmTagForStruct = "orm"
|
||||
OrmTagForStruct = gtag.ORM
|
||||
driverName = "clickhouse"
|
||||
)
|
||||
|
||||
|
@ -13,11 +13,11 @@ import (
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/net/goai"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
"github.com/gogf/gf/v2/util/gutil"
|
||||
)
|
||||
|
||||
@ -41,21 +41,21 @@ import (
|
||||
// DoRequestObj(ctx, req, &res)
|
||||
func (c *Client) DoRequestObj(ctx context.Context, req, res interface{}) error {
|
||||
var (
|
||||
method = gmeta.Get(req, goai.TagNameMethod).String()
|
||||
path = gmeta.Get(req, goai.TagNamePath).String()
|
||||
method = gmeta.Get(req, gtag.Method).String()
|
||||
path = gmeta.Get(req, gtag.Path).String()
|
||||
)
|
||||
if method == "" {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`no "%s" tag found in request object: %s`,
|
||||
goai.TagNameMethod, reflect.TypeOf(req).String(),
|
||||
gtag.Method, reflect.TypeOf(req).String(),
|
||||
)
|
||||
}
|
||||
if path == "" {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`no "%s" tag found in request object: %s`,
|
||||
goai.TagNamePath, reflect.TypeOf(req).String(),
|
||||
gtag.Path, reflect.TypeOf(req).String(),
|
||||
)
|
||||
}
|
||||
path = c.handlePathForObjRequest(path, req)
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
"github.com/gorilla/websocket"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gmap"
|
||||
@ -180,7 +181,7 @@ var (
|
||||
gracefulEnabled = false
|
||||
|
||||
// defaultValueTags are the struct tag names for default value storing.
|
||||
defaultValueTags = []string{"d", "default"}
|
||||
defaultValueTags = []string{gtag.DefaultShort, gtag.Default}
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -19,10 +19,10 @@ import (
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/consts"
|
||||
"github.com/gogf/gf/v2/net/goai"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -96,13 +96,13 @@ func (s *Server) setHandler(ctx context.Context, in setHandlerInput) {
|
||||
// Change the registered route according to meta info from its request structure.
|
||||
if handler.Info.Type != nil && handler.Info.Type.NumIn() == 2 {
|
||||
var objectReq = reflect.New(handler.Info.Type.In(1))
|
||||
if v := gmeta.Get(objectReq, goai.TagNamePath); !v.IsEmpty() {
|
||||
if v := gmeta.Get(objectReq, gtag.Path); !v.IsEmpty() {
|
||||
uri = v.String()
|
||||
}
|
||||
if v := gmeta.Get(objectReq, goai.TagNameMethod); !v.IsEmpty() {
|
||||
if v := gmeta.Get(objectReq, gtag.Method); !v.IsEmpty() {
|
||||
method = v.String()
|
||||
}
|
||||
if v := gmeta.Get(objectReq, goai.TagNameDomain); !v.IsEmpty() {
|
||||
if v := gmeta.Get(objectReq, gtag.Domain); !v.IsEmpty() {
|
||||
domain = v.String()
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
// OpenApiV3 is the structure defined from:
|
||||
@ -36,18 +37,6 @@ type OpenApiV3 struct {
|
||||
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
HttpMethodGet = `GET`
|
||||
HttpMethodPut = `PUT`
|
||||
HttpMethodPost = `POST`
|
||||
HttpMethodDelete = `DELETE`
|
||||
HttpMethodConnect = `CONNECT`
|
||||
HttpMethodHead = `HEAD`
|
||||
HttpMethodOptions = `OPTIONS`
|
||||
HttpMethodPatch = `PATCH`
|
||||
HttpMethodTrace = `TRACE`
|
||||
)
|
||||
|
||||
const (
|
||||
TypeInteger = `integer`
|
||||
TypeNumber = `number`
|
||||
@ -72,15 +61,6 @@ const (
|
||||
ParameterInCookie = `cookie`
|
||||
)
|
||||
|
||||
const (
|
||||
TagNamePath = `path`
|
||||
TagNameMethod = `method`
|
||||
TagNameMime = `mime`
|
||||
TagNameConsumes = `consumes`
|
||||
TagNameType = `type`
|
||||
TagNameDomain = `domain`
|
||||
)
|
||||
|
||||
const (
|
||||
validationRuleKeyForRequired = `required`
|
||||
validationRuleKeyForIn = `in:`
|
||||
@ -90,14 +70,14 @@ var (
|
||||
defaultReadContentTypes = []string{`application/json`}
|
||||
defaultWriteContentTypes = []string{`application/json`}
|
||||
shortTypeMapForTag = map[string]string{
|
||||
"d": "Default",
|
||||
"sum": "Summary",
|
||||
"sm": "Summary",
|
||||
"des": "Description",
|
||||
"dc": "Description",
|
||||
"eg": "Example",
|
||||
"egs": "Examples",
|
||||
"ed": "ExternalDocs",
|
||||
gtag.DefaultShort: gtag.Default,
|
||||
gtag.SummaryShort: gtag.Summary,
|
||||
gtag.SummaryShort2: gtag.Summary,
|
||||
gtag.DescriptionShort: gtag.Description,
|
||||
gtag.DescriptionShort2: gtag.Description,
|
||||
gtag.ExampleShort: gtag.Example,
|
||||
gtag.ExamplesShort: gtag.Examples,
|
||||
gtag.ExternalDocsShort: gtag.ExternalDocs,
|
||||
}
|
||||
)
|
||||
|
||||
@ -231,7 +211,7 @@ func (oai *OpenApiV3) golangTypeToSchemaName(t reflect.Type) string {
|
||||
return schemaName
|
||||
}
|
||||
|
||||
func (oai *OpenApiV3) fileMapWithShortTags(m map[string]string) map[string]string {
|
||||
func (oai *OpenApiV3) fillMapWithShortTags(m map[string]string) map[string]string {
|
||||
for k, v := range shortTypeMapForTag {
|
||||
if m[v] == "" && m[k] != "" {
|
||||
m[v] = m[k]
|
||||
|
@ -30,7 +30,7 @@ type Operation struct {
|
||||
}
|
||||
|
||||
func (oai *OpenApiV3) tagMapToOperation(tagMap map[string]string, operation *Operation) error {
|
||||
var mergedTagMap = oai.fileMapWithShortTags(tagMap)
|
||||
var mergedTagMap = oai.fillMapWithShortTags(tagMap)
|
||||
if err := gconv.Struct(mergedTagMap, operation); err != nil {
|
||||
return gerror.Wrap(err, `mapping struct tags to Operation failed`)
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ type Parameter struct {
|
||||
}
|
||||
|
||||
func (oai *OpenApiV3) tagMapToParameter(tagMap map[string]string, parameter *Parameter) error {
|
||||
var mergedTagMap = oai.fileMapWithShortTags(tagMap)
|
||||
var mergedTagMap = oai.fillMapWithShortTags(tagMap)
|
||||
if err := gconv.Struct(mergedTagMap, parameter); err != nil {
|
||||
return gerror.Wrap(err, `mapping struct tags to Parameter failed`)
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ package goai
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
@ -48,7 +49,7 @@ func (oai *OpenApiV3) newParameterRefWithStructMethod(field gstructs.Field, path
|
||||
} else {
|
||||
// Default the parameter input to "query" if method is "GET/DELETE".
|
||||
switch gstr.ToUpper(method) {
|
||||
case HttpMethodGet, HttpMethodDelete:
|
||||
case http.MethodGet, http.MethodDelete:
|
||||
parameter.In = ParameterInQuery
|
||||
|
||||
default:
|
||||
|
@ -7,6 +7,7 @@
|
||||
package goai
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
@ -17,6 +18,7 @@ import (
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
type Path struct {
|
||||
@ -97,7 +99,7 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
)
|
||||
// Path check.
|
||||
if in.Path == "" {
|
||||
in.Path = gmeta.Get(inputObject.Interface(), TagNamePath).String()
|
||||
in.Path = gmeta.Get(inputObject.Interface(), gtag.Path).String()
|
||||
if in.Prefix != "" {
|
||||
in.Path = gstr.TrimRight(in.Prefix, "/") + "/" + gstr.TrimLeft(in.Path, "/")
|
||||
}
|
||||
@ -106,7 +108,7 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeMissingParameter,
|
||||
`missing necessary path parameter "%s" for input struct "%s", missing tag in attribute Meta?`,
|
||||
TagNamePath, inputStructTypeName,
|
||||
gtag.Path, inputStructTypeName,
|
||||
)
|
||||
}
|
||||
|
||||
@ -116,13 +118,13 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
|
||||
// Method check.
|
||||
if in.Method == "" {
|
||||
in.Method = gmeta.Get(inputObject.Interface(), TagNameMethod).String()
|
||||
in.Method = gmeta.Get(inputObject.Interface(), gtag.Method).String()
|
||||
}
|
||||
if in.Method == "" {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeMissingParameter,
|
||||
`missing necessary method parameter "%s" for input struct "%s", missing tag in attribute Meta?`,
|
||||
TagNameMethod, inputStructTypeName,
|
||||
gtag.Method, inputStructTypeName,
|
||||
)
|
||||
}
|
||||
|
||||
@ -138,8 +140,8 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
return err
|
||||
}
|
||||
// Allowed request mime.
|
||||
if mime = inputMetaMap[TagNameMime]; mime == "" {
|
||||
mime = inputMetaMap[TagNameConsumes]
|
||||
if mime = inputMetaMap[gtag.Mime]; mime == "" {
|
||||
mime = inputMetaMap[gtag.Consumes]
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +181,7 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
// Supported mime types of request.
|
||||
var (
|
||||
contentTypes = oai.Config.ReadContentTypes
|
||||
tagMimeValue = gmeta.Get(inputObject.Interface(), TagNameMime).String()
|
||||
tagMimeValue = gmeta.Get(inputObject.Interface(), gtag.Mime).String()
|
||||
)
|
||||
if tagMimeValue != "" {
|
||||
contentTypes = gstr.SplitAndTrim(tagMimeValue, ",")
|
||||
@ -224,7 +226,7 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
// Supported mime types of response.
|
||||
var (
|
||||
contentTypes = oai.Config.ReadContentTypes
|
||||
tagMimeValue = gmeta.Get(outputObject.Interface(), TagNameMime).String()
|
||||
tagMimeValue = gmeta.Get(outputObject.Interface(), gtag.Mime).String()
|
||||
refInput = getResponseSchemaRefInput{
|
||||
BusinessStructName: outputStructTypeName,
|
||||
CommonResponseObject: oai.Config.CommonResponse,
|
||||
@ -256,35 +258,35 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
|
||||
// Assign to certain operation attribute.
|
||||
switch gstr.ToUpper(in.Method) {
|
||||
case HttpMethodGet:
|
||||
case http.MethodGet:
|
||||
// GET operations cannot have a requestBody.
|
||||
operation.RequestBody = nil
|
||||
path.Get = &operation
|
||||
|
||||
case HttpMethodPut:
|
||||
case http.MethodPut:
|
||||
path.Put = &operation
|
||||
|
||||
case HttpMethodPost:
|
||||
case http.MethodPost:
|
||||
path.Post = &operation
|
||||
|
||||
case HttpMethodDelete:
|
||||
case http.MethodDelete:
|
||||
// DELETE operations cannot have a requestBody.
|
||||
operation.RequestBody = nil
|
||||
path.Delete = &operation
|
||||
|
||||
case HttpMethodConnect:
|
||||
case http.MethodConnect:
|
||||
// Nothing to do for Connect.
|
||||
|
||||
case HttpMethodHead:
|
||||
case http.MethodHead:
|
||||
path.Head = &operation
|
||||
|
||||
case HttpMethodOptions:
|
||||
case http.MethodOptions:
|
||||
path.Options = &operation
|
||||
|
||||
case HttpMethodPatch:
|
||||
case http.MethodPatch:
|
||||
path.Patch = &operation
|
||||
|
||||
case HttpMethodTrace:
|
||||
case http.MethodTrace:
|
||||
path.Trace = &operation
|
||||
|
||||
default:
|
||||
@ -354,7 +356,7 @@ func (oai *OpenApiV3) doesStructHasNoFields(s interface{}) bool {
|
||||
}
|
||||
|
||||
func (oai *OpenApiV3) tagMapToPath(tagMap map[string]string, path *Path) error {
|
||||
var mergedTagMap = oai.fileMapWithShortTags(tagMap)
|
||||
var mergedTagMap = oai.fillMapWithShortTags(tagMap)
|
||||
if err := gconv.Struct(mergedTagMap, path); err != nil {
|
||||
return gerror.Wrap(err, `mapping struct tags to Path failed`)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ type Response struct {
|
||||
}
|
||||
|
||||
func (oai *OpenApiV3) tagMapToResponse(tagMap map[string]string, response *Response) error {
|
||||
var mergedTagMap = oai.fileMapWithShortTags(tagMap)
|
||||
var mergedTagMap = oai.fillMapWithShortTags(tagMap)
|
||||
if err := gconv.Struct(mergedTagMap, response); err != nil {
|
||||
return gerror.Wrap(err, `mapping struct tags to Response failed`)
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ func (oai *OpenApiV3) structToSchema(object interface{}) (*Schema, error) {
|
||||
}
|
||||
|
||||
func (oai *OpenApiV3) tagMapToSchema(tagMap map[string]string, schema *Schema) error {
|
||||
var mergedTagMap = oai.fileMapWithShortTags(tagMap)
|
||||
var mergedTagMap = oai.fillMapWithShortTags(tagMap)
|
||||
if err := gconv.Struct(mergedTagMap, schema); err != nil {
|
||||
return gerror.Wrap(err, `mapping struct tags to Schema failed`)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ package goai_test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
@ -96,14 +97,14 @@ func TestOpenApiV3_Add(t *testing.T) {
|
||||
)
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: "/test1/{appId}",
|
||||
Method: goai.HttpMethodPut,
|
||||
Method: http.MethodPut,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: "/test1/{appId}",
|
||||
Method: goai.HttpMethodPost,
|
||||
Method: http.MethodPost,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
@ -216,7 +217,7 @@ func TestOpenApiV3_Add_AutoDetectIn(t *testing.T) {
|
||||
)
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: path,
|
||||
Method: goai.HttpMethodGet,
|
||||
Method: http.MethodGet,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
@ -654,27 +655,27 @@ func TestOpenApiV3_CommonResponse_SubDataField(t *testing.T) {
|
||||
|
||||
func TestOpenApiV3_ShortTags(t *testing.T) {
|
||||
type CommonReq struct {
|
||||
AppId int64 `json:"appId" v:"required" in:"path" des:"应用Id" sum:"应用Id Summary"`
|
||||
ResourceId string `json:"resourceId" in:"query" des:"资源Id" sum:"资源Id Summary"`
|
||||
AppId int64 `json:"appId" v:"required" in:"path" dc:"应用Id" sm:"应用Id Summary"`
|
||||
ResourceId string `json:"resourceId" in:"query" dc:"资源Id" sm:"资源Id Summary"`
|
||||
}
|
||||
type SetSpecInfo struct {
|
||||
StorageType string `v:"required|in:CLOUD_PREMIUM,CLOUD_SSD,CLOUD_HSSD" des:"StorageType"`
|
||||
Shards int32 `des:"shards 分片数" sum:"Shards Summary"`
|
||||
Params []string `des:"默认参数(json 串-ClickHouseParams)" sum:"Params Summary"`
|
||||
StorageType string `v:"required|in:CLOUD_PREMIUM,CLOUD_SSD,CLOUD_HSSD" dc:"StorageType"`
|
||||
Shards int32 `dc:"shards 分片数" sm:"Shards Summary"`
|
||||
Params []string `dc:"默认参数(json 串-ClickHouseParams)" sm:"Params Summary"`
|
||||
}
|
||||
type CreateResourceReq struct {
|
||||
CommonReq
|
||||
gmeta.Meta `path:"/CreateResourceReq" method:"POST" tags:"default" sum:"CreateResourceReq sum"`
|
||||
Name string `des:"实例名称"`
|
||||
Product string `des:"业务类型"`
|
||||
Region string `v:"required" des:"区域"`
|
||||
SetMap map[string]*SetSpecInfo `v:"required" des:"配置Map"`
|
||||
SetSlice []SetSpecInfo `v:"required" des:"配置Slice"`
|
||||
gmeta.Meta `path:"/CreateResourceReq" method:"POST" tags:"default" sm:"CreateResourceReq sum"`
|
||||
Name string `dc:"实例名称"`
|
||||
Product string `dc:"业务类型"`
|
||||
Region string `v:"required" dc:"区域"`
|
||||
SetMap map[string]*SetSpecInfo `v:"required" dc:"配置Map"`
|
||||
SetSlice []SetSpecInfo `v:"required" dc:"配置Slice"`
|
||||
}
|
||||
|
||||
type CreateResourceRes struct {
|
||||
gmeta.Meta `des:"Demo Response Struct"`
|
||||
FlowId int64 `des:"创建实例流程id"`
|
||||
gmeta.Meta `dc:"Demo Response Struct"`
|
||||
FlowId int64 `dc:"创建实例流程id"`
|
||||
}
|
||||
|
||||
f := func(ctx context.Context, req *CreateResourceReq) (res *CreateResourceRes, err error) {
|
||||
@ -688,14 +689,14 @@ func TestOpenApiV3_ShortTags(t *testing.T) {
|
||||
)
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: "/test1/{appId}",
|
||||
Method: goai.HttpMethodPut,
|
||||
Method: http.MethodPut,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: "/test1/{appId}",
|
||||
Method: goai.HttpMethodPost,
|
||||
Method: http.MethodPost,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
@ -728,7 +729,7 @@ func TestOpenApiV3_HtmlResponse(t *testing.T) {
|
||||
)
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: "/test",
|
||||
Method: goai.HttpMethodGet,
|
||||
Method: http.MethodGet,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
@ -775,7 +776,7 @@ func TestOpenApiV3_HtmlResponseWithCommonResponse(t *testing.T) {
|
||||
|
||||
err = oai.Add(goai.AddInput{
|
||||
Path: "/test",
|
||||
Method: goai.HttpMethodGet,
|
||||
Method: http.MethodGet,
|
||||
Object: f,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
@ -23,18 +23,11 @@ import (
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
"github.com/gogf/gf/v2/util/gutil"
|
||||
"github.com/gogf/gf/v2/util/gvalid"
|
||||
)
|
||||
|
||||
const (
|
||||
tagNameDc = `dc` // description.
|
||||
tagNameAd = `ad` // additional
|
||||
tagNameEg = `eg` // examples.
|
||||
tagNameArg = `arg`
|
||||
tagNameRoot = `root`
|
||||
)
|
||||
|
||||
var (
|
||||
// defaultValueTags is the struct tag names for default value storing.
|
||||
defaultValueTags = []string{"d", "default"}
|
||||
@ -68,7 +61,7 @@ func NewFromObject(object interface{}) (rootCmd *Command, err error) {
|
||||
// Sub command creating.
|
||||
var (
|
||||
nameSet = gset.NewStrSet()
|
||||
rootCommandName = gmeta.Get(object, tagNameRoot).String()
|
||||
rootCommandName = gmeta.Get(object, gtag.Root).String()
|
||||
subCommands []*Command
|
||||
)
|
||||
if rootCommandName == "" {
|
||||
@ -155,14 +148,22 @@ func newCommandFromObjectMeta(object interface{}, name string) (command *Command
|
||||
}
|
||||
command.Name = name
|
||||
}
|
||||
if command.Brief == "" {
|
||||
for _, tag := range []string{gtag.Summary, gtag.SummaryShort, gtag.SummaryShort2} {
|
||||
command.Brief = metaData[tag]
|
||||
if command.Brief != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if command.Description == "" {
|
||||
command.Description = metaData[tagNameDc]
|
||||
command.Description = metaData[gtag.DescriptionShort]
|
||||
}
|
||||
if command.Examples == "" {
|
||||
command.Examples = metaData[tagNameEg]
|
||||
command.Examples = metaData[gtag.ExampleShort]
|
||||
}
|
||||
if command.Additional == "" {
|
||||
command.Additional = metaData[tagNameAd]
|
||||
command.Additional = metaData[gtag.AdditionalShort]
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -354,7 +355,7 @@ func newArgumentsFromInput(object interface{}) (args []Argument, err error) {
|
||||
arg.Short, reflect.TypeOf(object).String(), field.Name(),
|
||||
)
|
||||
}
|
||||
if v, ok := metaData[tagNameArg]; ok {
|
||||
if v, ok := metaData[gtag.Arg]; ok {
|
||||
arg.IsArg = gconv.Bool(v)
|
||||
}
|
||||
if nameSet.Contains(arg.Name) {
|
||||
|
@ -10,60 +10,35 @@
|
||||
// which means you cannot call them in runtime but in boot procedure.
|
||||
package gtag
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
const (
|
||||
Default = "default" // Default value tag of struct field for receiving parameters from HTTP request.
|
||||
DefaultShort = "d" // Short name of Default.
|
||||
Param = "param" // Parameter name for converting certain parameter to specified struct field.
|
||||
ParamShort = "p" // Short name of Param.
|
||||
Valid = "valid" // Validation rule tag for struct of field.
|
||||
ValidShort = "v" // Short name of Valid.
|
||||
NoValidation = "nv" // No validation for specified struct/field.
|
||||
ORM = "orm" // ORM tag for ORM feature, which performs different features according scenarios.
|
||||
Arg = "arg" // Arg tag for struct, usually for command argument option.
|
||||
Brief = "brief" // Brief tag for struct, usually be considered as summary.
|
||||
Root = "root" // Root tag for struct, usually for nested commands management.
|
||||
Additional = "additional" // Additional tag for struct, usually for additional description of command.
|
||||
AdditionalShort = "ad" // Short name of Additional.
|
||||
Path = `path` // Route path for HTTP request.
|
||||
Method = `method` // Route method for HTTP request.
|
||||
Domain = `domain` // Route domain for HTTP request.
|
||||
Mime = `mime` // MIME type for HTTP request/response.
|
||||
Consumes = `consumes` // MIME type for HTTP request.
|
||||
Summary = `summary` // Summary for struct, usually for OpenAPI in request struct.
|
||||
SummaryShort = `sm` // Short name of Summary.
|
||||
SummaryShort2 = `sum` // Short name of Summary.
|
||||
Description = `description` // Description for struct, usually for OpenAPI in request struct.
|
||||
DescriptionShort = `dc` // Short name of Description.
|
||||
DescriptionShort2 = `des` // Short name of Description.
|
||||
Example = `example` // Example for struct, usually for OpenAPI in request struct.
|
||||
ExampleShort = `eg` // Short name of Example.
|
||||
Examples = `examples` // Examples for struct, usually for OpenAPI in request struct.
|
||||
ExamplesShort = `egs` // Short name of Examples.
|
||||
ExternalDocs = `externalDocs` // External docs for struct, always for OpenAPI in request struct.
|
||||
ExternalDocsShort = `ed` // Short name of ExternalDocs.
|
||||
)
|
||||
|
||||
var (
|
||||
data = make(map[string]string)
|
||||
regex = regexp.MustCompile(`\{(.+?)\}`)
|
||||
)
|
||||
|
||||
// Set sets tag content for specified name.
|
||||
// Note that it panics if `name` already exists.
|
||||
func Set(name, value string) {
|
||||
if _, ok := data[name]; ok {
|
||||
panic(gerror.Newf(`value for tag name "%s" already exists`, name))
|
||||
}
|
||||
data[name] = value
|
||||
}
|
||||
|
||||
// SetOver performs as Set, but it overwrites the old value if `name` already exists.
|
||||
func SetOver(name, value string) {
|
||||
data[name] = value
|
||||
}
|
||||
|
||||
// Sets sets multiple tag content by map.
|
||||
func Sets(m map[string]string) {
|
||||
for k, v := range m {
|
||||
Set(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// SetsOver performs as Sets, but it overwrites the old value if `name` already exists.
|
||||
func SetsOver(m map[string]string) {
|
||||
for k, v := range m {
|
||||
SetOver(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Get retrieves and returns the stored tag content for specified name.
|
||||
func Get(name string) string {
|
||||
return data[name]
|
||||
}
|
||||
|
||||
// Parse parses and returns the content by replacing all tag name variable to
|
||||
// its content for given `content`.
|
||||
// Eg:
|
||||
// gtag.Set("demo", "content")
|
||||
// Parse(`This is {demo}`) -> `This is content`.
|
||||
func Parse(content string) string {
|
||||
return regex.ReplaceAllStringFunc(content, func(s string) string {
|
||||
if v, ok := data[s[1:len(s)-1]]; ok {
|
||||
return v
|
||||
}
|
||||
return s
|
||||
})
|
||||
}
|
||||
|
65
util/gtag/gtag_func.go
Normal file
65
util/gtag/gtag_func.go
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gtag
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
var (
|
||||
data = make(map[string]string)
|
||||
regex = regexp.MustCompile(`\{(.+?)\}`)
|
||||
)
|
||||
|
||||
// Set sets tag content for specified name.
|
||||
// Note that it panics if `name` already exists.
|
||||
func Set(name, value string) {
|
||||
if _, ok := data[name]; ok {
|
||||
panic(gerror.Newf(`value for tag name "%s" already exists`, name))
|
||||
}
|
||||
data[name] = value
|
||||
}
|
||||
|
||||
// SetOver performs as Set, but it overwrites the old value if `name` already exists.
|
||||
func SetOver(name, value string) {
|
||||
data[name] = value
|
||||
}
|
||||
|
||||
// Sets sets multiple tag content by map.
|
||||
func Sets(m map[string]string) {
|
||||
for k, v := range m {
|
||||
Set(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// SetsOver performs as Sets, but it overwrites the old value if `name` already exists.
|
||||
func SetsOver(m map[string]string) {
|
||||
for k, v := range m {
|
||||
SetOver(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Get retrieves and returns the stored tag content for specified name.
|
||||
func Get(name string) string {
|
||||
return data[name]
|
||||
}
|
||||
|
||||
// Parse parses and returns the content by replacing all tag name variable to
|
||||
// its content for given `content`.
|
||||
// Eg:
|
||||
// gtag.Set("demo", "content")
|
||||
// Parse(`This is {demo}`) -> `This is content`.
|
||||
func Parse(content string) string {
|
||||
return regex.ReplaceAllStringFunc(content, func(s string) string {
|
||||
if v, ok := data[s[1:len(s)-1]]; ok {
|
||||
return v
|
||||
}
|
||||
return s
|
||||
})
|
||||
}
|
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
// CustomMsg is the custom error message type,
|
||||
@ -42,7 +43,7 @@ const (
|
||||
internalErrorMapKey = "__InternalError__" // error map key for internal errors.
|
||||
internalDefaultRuleName = "__default__" // default rule name for i18n error message format if no i18n message found for specified error rule.
|
||||
ruleMessagePrefixForI18n = "gf.gvalid.rule." // prefix string for each rule configuration in i18n content.
|
||||
noValidationTagName = "nv" // no validation tag name for struct attribute.
|
||||
noValidationTagName = gtag.NoValidation // no validation tag name for struct attribute.
|
||||
ruleNameRegex = "regex" // the name for rule "regex"
|
||||
ruleNameNotRegex = "not-regex" // the name for rule "not-regex"
|
||||
ruleNameForeach = "foreach" // the name for rule "foreach"
|
||||
@ -60,8 +61,11 @@ var (
|
||||
internalDefaultRuleName: "The {field} value `{value}` is invalid",
|
||||
}
|
||||
|
||||
structTagPriority = []string{"gvalid", "valid", "v"} // structTagPriority specifies the validation tag priority array.
|
||||
aliasNameTagPriority = []string{"param", "params", "p"} // aliasNameTagPriority specifies the alias tag priority array.
|
||||
// structTagPriority specifies the validation tag priority array.
|
||||
structTagPriority = []string{gtag.Valid, gtag.ValidShort}
|
||||
|
||||
// aliasNameTagPriority specifies the alias tag priority array.
|
||||
aliasNameTagPriority = []string{gtag.Param, gtag.ParamShort}
|
||||
|
||||
// all internal error keys.
|
||||
internalErrKeyMap = map[string]string{
|
||||
|
@ -116,8 +116,8 @@ func Test_CheckStruct(t *testing.T) {
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username" gvalid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" gvalid:"password@required#登录密码不能为空"`
|
||||
Username string `json:"username" valid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" valid:"password@required#登录密码不能为空"`
|
||||
}
|
||||
var login LoginRequest
|
||||
err := g.Validator().Data(login).Run(context.TODO())
|
||||
@ -129,8 +129,8 @@ func Test_CheckStruct(t *testing.T) {
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username" gvalid:"@required#用户名不能为空"`
|
||||
Password string `json:"password" gvalid:"@required#登录密码不能为空"`
|
||||
Username string `json:"username" valid:"@required#用户名不能为空"`
|
||||
Password string `json:"password" valid:"@required#登录密码不能为空"`
|
||||
}
|
||||
var login LoginRequest
|
||||
err := g.Validator().Data(login).Run(context.TODO())
|
||||
@ -139,8 +139,8 @@ func Test_CheckStruct(t *testing.T) {
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type LoginRequest struct {
|
||||
username string `json:"username" gvalid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" gvalid:"password@required#登录密码不能为空"`
|
||||
username string `json:"username" valid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" valid:"password@required#登录密码不能为空"`
|
||||
}
|
||||
var login LoginRequest
|
||||
err := g.Validator().Data(login).Run(context.TODO())
|
||||
@ -151,10 +151,10 @@ func Test_CheckStruct(t *testing.T) {
|
||||
// gvalid tag
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int `gvalid:"uid@required|min:10#|ID不能为空"`
|
||||
Age int `gvalid:"age@required#年龄不能为空"`
|
||||
Username string `json:"username" gvalid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" gvalid:"password@required#登录密码不能为空"`
|
||||
Id int `valid:"uid@required|min:10#|ID不能为空"`
|
||||
Age int `valid:"age@required#年龄不能为空"`
|
||||
Username string `json:"username" valid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" valid:"password@required#登录密码不能为空"`
|
||||
}
|
||||
user := &User{
|
||||
Id: 1,
|
||||
@ -169,10 +169,10 @@ func Test_CheckStruct(t *testing.T) {
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int `gvalid:"uid@required|min:10#|ID不能为空"`
|
||||
Age int `gvalid:"age@required#年龄不能为空"`
|
||||
Username string `json:"username" gvalid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" gvalid:"password@required#登录密码不能为空"`
|
||||
Id int `valid:"uid@required|min:10#|ID不能为空"`
|
||||
Age int `valid:"age@required#年龄不能为空"`
|
||||
Username string `json:"username" valid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" valid:"password@required#登录密码不能为空"`
|
||||
}
|
||||
user := &User{
|
||||
Id: 1,
|
||||
@ -192,10 +192,10 @@ func Test_CheckStruct(t *testing.T) {
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int `gvalid:"uid@required|min:10#ID不能为空"`
|
||||
Age int `gvalid:"age@required#年龄不能为空"`
|
||||
Username string `json:"username" gvalid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" gvalid:"password@required#登录密码不能为空"`
|
||||
Id int `valid:"uid@required|min:10#ID不能为空"`
|
||||
Age int `valid:"age@required#年龄不能为空"`
|
||||
Username string `json:"username" valid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" valid:"password@required#登录密码不能为空"`
|
||||
}
|
||||
user := &User{
|
||||
Id: 1,
|
||||
@ -212,8 +212,8 @@ func Test_CheckStruct(t *testing.T) {
|
||||
type User struct {
|
||||
Id int `valid:"uid@required|min:10#|ID不能为空"`
|
||||
Age int `valid:"age@required#年龄不能为空"`
|
||||
Username string `json:"username" gvalid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" gvalid:"password@required#登录密码不能为空"`
|
||||
Username string `json:"username" valid:"username@required#用户名不能为空"`
|
||||
Password string `json:"password" valid:"password@required#登录密码不能为空"`
|
||||
}
|
||||
user := &User{
|
||||
Id: 1,
|
||||
|
Loading…
Reference in New Issue
Block a user