diff --git a/core/descriptor.go b/core/descriptor.go index b0fddb2..c5faf71 100644 --- a/core/descriptor.go +++ b/core/descriptor.go @@ -16,7 +16,7 @@ import ( var ( VerInfo = &VersionInfo{ - MirVer: "v4.0.0", + MirVer: "v4.1.0", } ) @@ -41,6 +41,7 @@ type FieldDescriptor struct { HttpMethods []string IsAnyMethod bool IsFieldChain bool + IsUseContext bool IsBindIn bool IsRenderOut bool In reflect.Type diff --git a/examples/go.mod b/examples/go.mod index 3208429..85d7a78 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -35,3 +35,5 @@ require ( gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/alimy/mir/v4 => ../ \ No newline at end of file diff --git a/examples/mirc/auto/api/site.go b/examples/mirc/auto/api/site.go index 22efe36..e0d38b8 100644 --- a/examples/mirc/auto/api/site.go +++ b/examples/mirc/auto/api/site.go @@ -1,6 +1,6 @@ // Code generated by go-mir. DO NOT EDIT. // versions: -// - mir v4.0.0 +// - mir v4.1.0 package api @@ -24,9 +24,10 @@ type _default_ interface { Render(*gin.Context, any, mir.Error) } -type LogoutReq struct { +type LoginReq struct { AgentInfo AgentInfo `json:"agent_info"` Name string `json:"name"` + Passwd string `json:"passwd"` } type AgentInfo struct { @@ -34,12 +35,6 @@ type AgentInfo struct { UserAgent string `json:"user_agent"` } -type LoginReq struct { - AgentInfo AgentInfo `json:"agent_info"` - Name string `json:"name"` - Passwd string `json:"passwd"` -} - type LoginResp struct { UserInfo ServerInfo ServerInfo `json:"server_info"` @@ -54,6 +49,11 @@ type UserInfo struct { Name string `json:"name"` } +type LogoutReq struct { + AgentInfo AgentInfo `json:"agent_info"` + Name string `json:"name"` +} + type TweetsReq struct { Date string `json:"date"` } @@ -74,6 +74,13 @@ type Site interface { // Chain provide handlers chain for gin Chain() gin.HandlersChain + MultiAttachments(*gin.Context) + ManyResources(*gin.Context) + AnyStaticks(*gin.Context) + Assets(*gin.Context) + SimpleUpload(*gin.Context) + FileUpload(*gin.Context) + ImageUpload(*gin.Context) Logout(*LogoutReq) mir.Error Login(*LoginReq) (*LoginResp, mir.Error) PrevTweets(*TweetsReq) (*TweetsResp, mir.Error) @@ -86,6 +93,9 @@ type Site interface { } type SiteChain interface { + ChainMultiAttachments() gin.HandlersChain + ChainSimpleUpload() gin.HandlersChain + ChainFileUpload() gin.HandlersChain ChainIndex() gin.HandlersChain mustEmbedUnimplementedSiteChain() @@ -105,6 +115,23 @@ func RegisterSiteServant(e *gin.Engine, s Site, m ...SiteChain) { router.Use(middlewares...) // register routes info to router + { + h := append(cc.ChainMultiAttachments(), s.MultiAttachments) + router.Handle("OPTIONS", "/attachments", h...) + router.Handle("HEAD", "/attachments", h...) + router.Handle("GET", "/attachments", h...) + } + { + h := s.ManyResources + router.Handle("OPTIONS", "/resources", h) + router.Handle("HEAD", "/resources", h) + router.Handle("GET", "/resources", h) + } + router.Any("/staticks", s.AnyStaticks) + router.Handle("GET", "/assets", s.Assets) + router.Handle("POST", "/upload/simple", append(cc.ChainSimpleUpload(), s.SimpleUpload)...) + router.Handle("POST", "/upload/file", append(cc.ChainFileUpload(), s.FileUpload)...) + router.Handle("POST", "/upload/image", s.ImageUpload) router.Handle("POST", "/user/logout/", func(c *gin.Context) { select { case <-c.Request.Context().Done(): @@ -201,6 +228,34 @@ func (UnimplementedSiteServant) Chain() gin.HandlersChain { return nil } +func (UnimplementedSiteServant) MultiAttachments(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) ManyResources(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) AnyStaticks(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) Assets(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) SimpleUpload(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) FileUpload(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) ImageUpload(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + func (UnimplementedSiteServant) Logout(req *LogoutReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } @@ -234,6 +289,18 @@ func (UnimplementedSiteServant) mustEmbedUnimplementedSiteServant() {} // UnimplementedSiteChain can be embedded to have forward compatible implementations. type UnimplementedSiteChain struct{} +func (b *UnimplementedSiteChain) ChainMultiAttachments() gin.HandlersChain { + return nil +} + +func (b *UnimplementedSiteChain) ChainSimpleUpload() gin.HandlersChain { + return nil +} + +func (b *UnimplementedSiteChain) ChainFileUpload() gin.HandlersChain { + return nil +} + func (b *UnimplementedSiteChain) ChainIndex() gin.HandlersChain { return nil } diff --git a/examples/mirc/auto/api/v1/admin.go b/examples/mirc/auto/api/v1/admin.go index b127e93..f459669 100644 --- a/examples/mirc/auto/api/v1/admin.go +++ b/examples/mirc/auto/api/v1/admin.go @@ -1,6 +1,6 @@ // Code generated by go-mir. DO NOT EDIT. // versions: -// - mir v4.0.0 +// - mir v4.1.0 package v1 diff --git a/examples/mirc/auto/api/v1/site.go b/examples/mirc/auto/api/v1/site.go index 760ddb9..94cea2c 100644 --- a/examples/mirc/auto/api/v1/site.go +++ b/examples/mirc/auto/api/v1/site.go @@ -1,6 +1,6 @@ // Code generated by go-mir. DO NOT EDIT. // versions: -// - mir v4.0.0 +// - mir v4.1.0 package v1 @@ -17,6 +17,10 @@ type Site interface { // Chain provide handlers chain for gin Chain() gin.HandlersChain + MultiAttachments(*gin.Context) + ManyResources(*gin.Context) + AnyStaticks(*gin.Context) + Assets(*gin.Context) Logout() mir.Error Articles() mir.Error AnyTopics() mir.Error @@ -26,6 +30,7 @@ type Site interface { } type SiteChain interface { + ChainMultiAttachments() gin.HandlersChain ChainArticles() gin.HandlersChain ChainAnyTopics() gin.HandlersChain ChainIndex() gin.HandlersChain @@ -47,6 +52,20 @@ func RegisterSiteServant(e *gin.Engine, s Site, m ...SiteChain) { router.Use(middlewares...) // register routes info to router + { + h := append(cc.ChainMultiAttachments(), s.MultiAttachments) + router.Handle("OPTIONS", "/attachments", h...) + router.Handle("HEAD", "/attachments", h...) + router.Handle("GET", "/attachments", h...) + } + { + h := s.ManyResources + router.Handle("OPTIONS", "/resources", h) + router.Handle("HEAD", "/resources", h) + router.Handle("GET", "/resources", h) + } + router.Any("/staticks", s.AnyStaticks) + router.Handle("GET", "/assets", s.Assets) router.Handle("POST", "/user/logout/", func(c *gin.Context) { select { case <-c.Request.Context().Done(): @@ -97,6 +116,22 @@ func (UnimplementedSiteServant) Chain() gin.HandlersChain { return nil } +func (UnimplementedSiteServant) MultiAttachments(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) ManyResources(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) AnyStaticks(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) Assets(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + func (UnimplementedSiteServant) Logout() mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } @@ -118,6 +153,10 @@ func (UnimplementedSiteServant) mustEmbedUnimplementedSiteServant() {} // UnimplementedSiteChain can be embedded to have forward compatible implementations. type UnimplementedSiteChain struct{} +func (b *UnimplementedSiteChain) ChainMultiAttachments() gin.HandlersChain { + return nil +} + func (b *UnimplementedSiteChain) ChainArticles() gin.HandlersChain { return nil } diff --git a/examples/mirc/auto/api/v2/site.go b/examples/mirc/auto/api/v2/site.go index daa605b..11a4fc3 100644 --- a/examples/mirc/auto/api/v2/site.go +++ b/examples/mirc/auto/api/v2/site.go @@ -1,6 +1,6 @@ // Code generated by go-mir. DO NOT EDIT. // versions: -// - mir v4.0.0 +// - mir v4.1.0 package v2 @@ -66,6 +66,13 @@ type Tweet struct { type Site interface { _default_ + MultiAttachments(*gin.Context) + ManyResources(*gin.Context) + AnyStaticks(*gin.Context) + Assets(*gin.Context) + SimpleUpload(*gin.Context) + FileUpload(*gin.Context) + ImageUpload(*gin.Context) Logout() mir.Error Login(*LoginReq) (*LoginResp, mir.Error) PrevTweets(*TweetsReq) (*TweetsResp, mir.Error) @@ -77,6 +84,9 @@ type Site interface { } type SiteChain interface { + ChainMultiAttachments() gin.HandlersChain + ChainSimpleUpload() gin.HandlersChain + ChainFileUpload() gin.HandlersChain ChainIndex() gin.HandlersChain mustEmbedUnimplementedSiteChain() @@ -93,6 +103,23 @@ func RegisterSiteServant(e *gin.Engine, s Site, m ...SiteChain) { router := e.Group("v2") // register routes info to router + { + h := append(cc.ChainMultiAttachments(), s.MultiAttachments) + router.Handle("OPTIONS", "/attachments", h...) + router.Handle("HEAD", "/attachments", h...) + router.Handle("GET", "/attachments", h...) + } + { + h := s.ManyResources + router.Handle("OPTIONS", "/resources", h) + router.Handle("HEAD", "/resources", h) + router.Handle("GET", "/resources", h) + } + router.Any("/staticks", s.AnyStaticks) + router.Handle("GET", "/assets", s.Assets) + router.Handle("POST", "/upload/simple", append(cc.ChainSimpleUpload(), s.SimpleUpload)...) + router.Handle("POST", "/upload/file", append(cc.ChainFileUpload(), s.FileUpload)...) + router.Handle("POST", "/upload/image", s.ImageUpload) router.Handle("POST", "/user/logout/", func(c *gin.Context) { select { case <-c.Request.Context().Done(): @@ -131,9 +158,9 @@ func RegisterSiteServant(e *gin.Engine, s Site, m ...SiteChain) { resp, err := s.PrevTweets(req) s.Render(c, resp, err) } - router.Handle("POST", "/tweets/prev/", h) router.Handle("HEAD", "/tweets/prev/", h) router.Handle("GET", "/tweets/prev/", h) + router.Handle("POST", "/tweets/prev/", h) } router.Any("/tweets/next/", func(c *gin.Context) { select { @@ -172,6 +199,34 @@ func RegisterSiteServant(e *gin.Engine, s Site, m ...SiteChain) { // UnimplementedSiteServant can be embedded to have forward compatible implementations. type UnimplementedSiteServant struct{} +func (UnimplementedSiteServant) MultiAttachments(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) ManyResources(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) AnyStaticks(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) Assets(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) SimpleUpload(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) FileUpload(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) ImageUpload(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + func (UnimplementedSiteServant) Logout() mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } @@ -201,6 +256,18 @@ func (UnimplementedSiteServant) mustEmbedUnimplementedSiteServant() {} // UnimplementedSiteChain can be embedded to have forward compatible implementations. type UnimplementedSiteChain struct{} +func (b *UnimplementedSiteChain) ChainMultiAttachments() gin.HandlersChain { + return nil +} + +func (b *UnimplementedSiteChain) ChainSimpleUpload() gin.HandlersChain { + return nil +} + +func (b *UnimplementedSiteChain) ChainFileUpload() gin.HandlersChain { + return nil +} + func (b *UnimplementedSiteChain) ChainIndex() gin.HandlersChain { return nil } diff --git a/examples/mirc/auto/api/v3/site.go b/examples/mirc/auto/api/v3/site.go index d66430c..b5095ad 100644 --- a/examples/mirc/auto/api/v3/site.go +++ b/examples/mirc/auto/api/v3/site.go @@ -1,6 +1,6 @@ // Code generated by go-mir. DO NOT EDIT. // versions: -// - mir v4.0.0 +// - mir v4.1.0 package v3 @@ -28,6 +28,10 @@ type _default_ interface { type Site interface { _default_ + MultiAttachments(*gin.Context) + ManyResources(*gin.Context) + AnyStaticks(*gin.Context) + Assets(*gin.Context) Logout() mir.Error Login(*model.LoginReq) (*model.LoginResp, mir.Error) PrevTweets(*model.TweetsReq) (*model.TweetsResp, mir.Error) @@ -38,11 +42,37 @@ type Site interface { mustEmbedUnimplementedSiteServant() } +type SiteChain interface { + ChainMultiAttachments() gin.HandlersChain + + mustEmbedUnimplementedSiteChain() +} + // RegisterSiteServant register Site servant to gin -func RegisterSiteServant(e *gin.Engine, s Site) { +func RegisterSiteServant(e *gin.Engine, s Site, m ...SiteChain) { + var cc SiteChain + if len(m) > 0 { + cc = m[0] + } else { + cc = &UnimplementedSiteChain{} + } router := e.Group("v3") // register routes info to router + { + h := append(cc.ChainMultiAttachments(), s.MultiAttachments) + router.Handle("OPTIONS", "/attachments", h...) + router.Handle("HEAD", "/attachments", h...) + router.Handle("GET", "/attachments", h...) + } + { + h := s.ManyResources + router.Handle("OPTIONS", "/resources", h) + router.Handle("HEAD", "/resources", h) + router.Handle("GET", "/resources", h) + } + router.Any("/staticks", s.AnyStaticks) + router.Handle("GET", "/assets", s.Assets) router.Handle("POST", "/user/logout/", func(c *gin.Context) { select { case <-c.Request.Context().Done(): @@ -87,9 +117,9 @@ func RegisterSiteServant(e *gin.Engine, s Site) { resp, err := s.PrevTweets(req) s.Render(c, resp, err) } + router.Handle("HEAD", "/tweets/prev/", h) router.Handle("GET", "/tweets/prev/", h) router.Handle("POST", "/tweets/prev/", h) - router.Handle("HEAD", "/tweets/prev/", h) } router.Any("/tweets/next/", func(c *gin.Context) { select { @@ -128,6 +158,22 @@ func RegisterSiteServant(e *gin.Engine, s Site) { // UnimplementedSiteServant can be embedded to have forward compatible implementations. type UnimplementedSiteServant struct{} +func (UnimplementedSiteServant) MultiAttachments(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) ManyResources(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) AnyStaticks(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedSiteServant) Assets(c *gin.Context) { + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + func (UnimplementedSiteServant) Logout() mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } @@ -153,3 +199,12 @@ func (UnimplementedSiteServant) Index() mir.Error { } func (UnimplementedSiteServant) mustEmbedUnimplementedSiteServant() {} + +// UnimplementedSiteChain can be embedded to have forward compatible implementations. +type UnimplementedSiteChain struct{} + +func (b *UnimplementedSiteChain) ChainMultiAttachments() gin.HandlersChain { + return nil +} + +func (b *UnimplementedSiteChain) mustEmbedUnimplementedSiteChain() {} diff --git a/examples/mirc/routes/site.go b/examples/mirc/routes/site.go index b012959..9081837 100644 --- a/examples/mirc/routes/site.go +++ b/examples/mirc/routes/site.go @@ -75,12 +75,19 @@ func (r *LoginResp) Render(c *gin.Context) { // Site site interface info type Site struct { - Chain `mir:"-"` - Index func(Get, Chain) `mir:"/index/"` - Articles func(Get) `mir:"/articles/:category/"` - AnyTopics func() `mir:"/topics/"` - NextTweets func(Any, TweetsReq) TweetsResp `mir:"/tweets/next/"` - PrevTweets func(Post, Get, Head, TweetsReq) TweetsResp `mir:"/tweets/prev/"` - Login func(Post, LoginReq) LoginResp `mir:"/user/login/"` - Logout func(Post, LogoutReq) `mir:"/user/logout/"` + Chain `mir:"-"` + Index func(Get, Chain) `mir:"/index/"` + Articles func(Get) `mir:"/articles/:category/"` + AnyTopics func() `mir:"/topics/"` + NextTweets func(Any, TweetsReq) TweetsResp `mir:"/tweets/next/"` + PrevTweets func(Post, Get, Head, TweetsReq) TweetsResp `mir:"/tweets/prev/"` + Login func(Post, LoginReq) LoginResp `mir:"/user/login/"` + Logout func(Post, LogoutReq) `mir:"/user/logout/"` + ImageUpload func(Post, Context) `mir:"/upload/image"` + FileUpload func(Post, Chain, Context) `mir:"/upload/file"` + SimpleUpload func(Post, Chain, Context, LoginReq) LoginResp `mir:"/upload/simple"` + Assets func(Get, Context) `mir:"/assets"` + AnyStaticks func(Any, Context) `mir:"/staticks"` + ManyResources func(Get, Head, Options, Context) `mir:"/resources"` + MultiAttachments func(Get, Head, Options, Chain, Context) `mir:"/attachments"` } diff --git a/examples/mirc/routes/v1/site.go b/examples/mirc/routes/v1/site.go index bc30b95..8f7858e 100644 --- a/examples/mirc/routes/v1/site.go +++ b/examples/mirc/routes/v1/site.go @@ -15,12 +15,16 @@ func init() { // Site site v1 interface info type Site struct { - Chain `mir:"-"` - Group `mir:"v1"` - Index func(Get, Chain) `mir:"/index/"` - AnyTopics func(Chain) `mir:"/topics/"` - Articles func(Head, Get, Post, Chain) `mir:"/articles/:category/"` - Logout func(Post) `mir:"/user/logout/"` + Chain `mir:"-"` + Group `mir:"v1"` + Index func(Get, Chain) `mir:"/index/"` + AnyTopics func(Chain) `mir:"/topics/"` + Articles func(Head, Get, Post, Chain) `mir:"/articles/:category/"` + Logout func(Post) `mir:"/user/logout/"` + Assets func(Get, Context) `mir:"/assets"` + AnyStaticks func(Any, Context) `mir:"/staticks"` + ManyResources func(Get, Head, Options, Context) `mir:"/resources"` + MultiAttachments func(Get, Head, Options, Chain, Context) `mir:"/attachments"` } // Admin admin v1 interface info diff --git a/examples/mirc/routes/v2/site.go b/examples/mirc/routes/v2/site.go index 70e5215..3bfaf0c 100644 --- a/examples/mirc/routes/v2/site.go +++ b/examples/mirc/routes/v2/site.go @@ -54,11 +54,18 @@ type Tweet struct { // Site site v2 interface info type Site struct { - Group `mir:"v2"` - Index func(Get, Chain) `mir:"/index/"` - Articles func(Get) `mir:"/articles/:category/"` - NextTweets func(Any, TweetsReq) TweetsResp `mir:"/tweets/next/"` - PrevTweets func(Post, Get, Head, TweetsReq) TweetsResp `mir:"/tweets/prev/"` - Login func(Post, LoginReq) LoginResp `mir:"/user/login/"` - Logout func(Post) `mir:"/user/logout/"` + Group `mir:"v2"` + Index func(Get, Chain) `mir:"/index/"` + Articles func(Get) `mir:"/articles/:category/"` + NextTweets func(Any, TweetsReq) TweetsResp `mir:"/tweets/next/"` + PrevTweets func(Post, Get, Head, TweetsReq) TweetsResp `mir:"/tweets/prev/"` + Login func(Post, LoginReq) LoginResp `mir:"/user/login/"` + Logout func(Post) `mir:"/user/logout/"` + ImageUpload func(Post, Context) `mir:"/upload/image"` + FileUpload func(Post, Chain, Context) `mir:"/upload/file"` + SimpleUpload func(Post, Chain, Context, LoginReq) LoginResp `mir:"/upload/simple"` + Assets func(Get, Context) `mir:"/assets"` + AnyStaticks func(Any, Context) `mir:"/staticks"` + ManyResources func(Get, Head, Options, Context) `mir:"/resources"` + MultiAttachments func(Get, Head, Options, Chain, Context) `mir:"/attachments"` } diff --git a/examples/mirc/routes/v3/site.go b/examples/mirc/routes/v3/site.go index 248e5cf..3f70363 100644 --- a/examples/mirc/routes/v3/site.go +++ b/examples/mirc/routes/v3/site.go @@ -16,11 +16,15 @@ func init() { // Site site v3 interface info type Site struct { - Group `mir:"v3"` - Index func(Get) `mir:"/index/"` - Articles func(Get) `mir:"/articles/:category/"` - NextTweets func(Any, model.TweetsReq) model.TweetsResp `mir:"/tweets/next/"` - PrevTweets func(Post, Get, Head, model.TweetsReq) model.TweetsResp `mir:"/tweets/prev/"` - Login func(Post, model.LoginReq) model.LoginResp `mir:"/user/login/"` - Logout func(Post) `mir:"/user/logout/"` + Group `mir:"v3"` + Index func(Get) `mir:"/index/"` + Articles func(Get) `mir:"/articles/:category/"` + NextTweets func(Any, model.TweetsReq) model.TweetsResp `mir:"/tweets/next/"` + PrevTweets func(Post, Get, Head, model.TweetsReq) model.TweetsResp `mir:"/tweets/prev/"` + Login func(Post, model.LoginReq) model.LoginResp `mir:"/user/login/"` + Logout func(Post) `mir:"/user/logout/"` + Assets func(Get, Context) `mir:"/assets"` + AnyStaticks func(Any, Context) `mir:"/staticks"` + ManyResources func(Get, Head, Options, Context) `mir:"/resources"` + MultiAttachments func(Get, Head, Options, Chain, Context) `mir:"/attachments"` } diff --git a/examples/servants/core.go b/examples/servants/core.go index 96a2551..58b91e2 100644 --- a/examples/servants/core.go +++ b/examples/servants/core.go @@ -26,4 +26,5 @@ func (baseSrv) Render(c *gin.Context, data any, err mir.Error) { } else { c.JSON(err.StatusCode(), err.Error()) } + c.String(http.StatusNotImplemented, "") } diff --git a/internal/generator/templates/gin_iface.tmpl b/internal/generator/templates/gin_iface.tmpl index 711ac5a..2e1631a 100644 --- a/internal/generator/templates/gin_iface.tmpl +++ b/internal/generator/templates/gin_iface.tmpl @@ -35,7 +35,7 @@ type {{.TypeName}} interface { {{if notEmptyStr .Chain }}// Chain provide handlers chain for gin {{.Chain}}() gin.HandlersChain {{end}} -{{range .Fields}} {{.MethodName}}({{if notEmptyStr .InName }}*{{ .InName }}{{end}}) {{if notEmptyStr .OutName }}(*{{ .OutName}}, mir.Error){{else}}mir.Error{{end}} +{{range .Fields}} {{if .IsUseContext}}{{ .MethodName}}(*gin.Context){{else}}{{.MethodName}}({{if notEmptyStr .InName }}*{{ .InName }}{{end}}) {{if notEmptyStr .OutName }}(*{{ .OutName}}, mir.Error){{else}}mir.Error{{end}}{{end}} {{end}} mustEmbedUnimplemented{{.TypeName}}Servant() @@ -65,7 +65,7 @@ func Register{{.TypeName}}Servant(e *gin.Engine, s {{.TypeName}}{{if .IsUseField router.Use(middlewares...) {{end}} // register routes info to router -{{range .Fields}}{{if .NotHttpAny }} router.Handle("{{.HttpMethod}}", "{{.Path}}", {{if .IsFieldChain }}append(cc.Chain{{.MethodName}}(), {{end}}func(c *gin.Context) { +{{range .Fields}}{{if .NotHttpAny }} router.Handle("{{.HttpMethod}}", "{{.Path}}", {{if .IsFieldChain }}append(cc.Chain{{.MethodName}}(), {{end}}{{if .IsUseContext}}s.{{ .MethodName}}{{else}}func(c *gin.Context) { {{- if $.WatchCtxDone }} select { case <- c.Request.Context().Done(): @@ -100,8 +100,8 @@ func Register{{.TypeName}}Servant(e *gin.Engine, s {{.TypeName}}{{if .IsUseField {{- else -}} s.Render(c, nil, s.{{.MethodName}}({{if notEmptyStr .InName}}req{{end}})) {{- end }} - }{{if .IsFieldChain }})...{{end}}) - {{else if .JustHttpAny}} router.Any("{{.Path}}", {{if .IsFieldChain }}append(cc.Chain{{.MethodName}}(), {{end}}func(c *gin.Context) { + }{{end}}{{if .IsFieldChain }})...{{end}}) + {{else if .JustHttpAny}} router.Any("{{.Path}}", {{if .IsFieldChain }}append(cc.Chain{{.MethodName}}(), {{end}}{{if .IsUseContext}}s.{{ .MethodName}}{{else}}func(c *gin.Context) { {{- if $.WatchCtxDone }} select { case <- c.Request.Context().Done(): @@ -136,9 +136,9 @@ func Register{{.TypeName}}Servant(e *gin.Engine, s {{.TypeName}}{{if .IsUseField {{- else -}} s.Render(c, nil, s.{{.MethodName}}({{if notEmptyStr .InName}}req{{end}})) {{- end }} - }{{if .IsFieldChain }})...{{end}}) + }{{end}}{{if .IsFieldChain }})...{{end}}) {{else}}{{$field := .}} { - h := {{if .IsFieldChain }}append(cc.Chain{{.MethodName}}(), {{end}}func(c *gin.Context) { + h := {{if .IsFieldChain }}append(cc.Chain{{.MethodName}}(), {{end}}{{if .IsUseContext}}s.{{ .MethodName}}{{else}}func(c *gin.Context) { {{- if $.WatchCtxDone }} select { case <- c.Request.Context().Done(): @@ -173,7 +173,7 @@ func Register{{.TypeName}}Servant(e *gin.Engine, s {{.TypeName}}{{if .IsUseField {{- else -}} s.Render(c, nil, s.{{.MethodName}}({{if notEmptyStr .InName}}req{{end}})) {{- end }} - }{{if .IsFieldChain }}){{end}} + }{{end}}{{if .IsFieldChain }}){{end}} {{range .AnyHttpMethods}} router.Handle("{{.}}", "{{$field.Path}}", h{{if $field.IsFieldChain }}...{{end}}) {{end}} } {{end}} @@ -191,8 +191,12 @@ func ({{$unimplementedServant}}){{.Chain}}() gin.HandlersChain { {{end}} {{range .Fields}} -func ({{$unimplementedServant}}){{.MethodName}}({{if notEmptyStr .InName }}req *{{ .InName }}{{end}}) {{if notEmptyStr .OutName }}(*{{ .OutName}}, mir.Error){{else}}mir.Error{{end}} { +func ({{$unimplementedServant}}){{if .IsUseContext}}{{ .MethodName}}(c *gin.Context){{else}}{{.MethodName}}({{if notEmptyStr .InName }}req *{{ .InName }}{{end}}) {{if notEmptyStr .OutName }}(*{{ .OutName}}, mir.Error){{else}}mir.Error{{end}}{{end}} { + {{if .IsUseContext -}} + c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) + {{else -}} return {{if notEmptyStr .OutName }}nil, {{end}}mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) + {{end -}} } {{end}} diff --git a/internal/reflex/field.go b/internal/reflex/field.go index 5d384a1..6c68d67 100644 --- a/internal/reflex/field.go +++ b/internal/reflex/field.go @@ -41,6 +41,7 @@ func (e tagError) Error() string { type tagInfo struct { isAnyMethod bool // isAnyMethod indicate whether method is Any isFieldChain bool // isFieldChain indicate whether method is need field chain + isUseContext bool // isUseContext indicate whether method is just use Context methods utils.HttpMethodSet // method indicate methods information in struct tag string host string // host indicate host information in struct tag string path string // path indicate path information in struct tag string @@ -151,6 +152,8 @@ func (r *reflex) tagInfoFrom(field reflect.StructField, pkgPath string) (*tagInf info.methods.Add(mir.HttpMethods...) case "Chain": info.isFieldChain = true + case "Context": + info.isUseContext = true } } } diff --git a/internal/reflex/reflex.go b/internal/reflex/reflex.go index 42ca699..9de71ff 100644 --- a/internal/reflex/reflex.go +++ b/internal/reflex/reflex.go @@ -134,6 +134,7 @@ func (r *reflex) fieldFrom(t *tagInfo, pkgPath string) *core.FieldDescriptor { PkgPath: pkgPath, IsAnyMethod: t.isAnyMethod, IsFieldChain: t.isFieldChain, + IsUseContext: t.isUseContext, HttpMethods: t.methods.List(), IsBindIn: t.isBindIn, IsRenderOut: t.isRenderOut, diff --git a/mir.go b/mir.go index 5c3b9dd..bbd4bfc 100644 --- a/mir.go +++ b/mir.go @@ -10,6 +10,10 @@ type Group any // Chain indicator a Handler slice used register Middleware to router by group type Chain any +// Context indicator a handler that just use engine's context like use gin engine +// the handler will just take a function func(c *gin.Context) as handler +type Context any + // Get indicator a GET method handler used placeholder register info in struct tag type Get any