make the macro#Parse to return a value of a Template instead of its ptr and debug logs for handlers length ignores the internal generated macro evaluator handler if it is there, so end-dev cannot be confused about the debug logs at that point

Former-commit-id: c23a3d10b43f145de575f1ea11e3dbf9bbd33a6b
This commit is contained in:
Gerasimos (Makis) Maropoulos 2018-09-29 19:59:39 +03:00
parent 4431a65a56
commit b08df3a785
6 changed files with 45 additions and 28 deletions

View File

@ -72,7 +72,7 @@ func main() {
)
ctx.Writef("myparam1: %s | myparam2: %s", myparam1, myparam2)
})
}, func(ctx context.Context) {})
app.Get("/test_string2/{myparam1}/{myparam2}", func(ctx context.Context) {
var (

View File

@ -33,7 +33,7 @@ func WildcardParam(name string) string {
return prefix(name, WildcardParamStart)
}
func convertMacroTmplToNodePath(tmpl *macro.Template) string {
func convertMacroTmplToNodePath(tmpl macro.Template) string {
routePath := tmpl.Src
if len(tmpl.Params) > 0 {
if routePath[len(routePath)-1] == '/' {

View File

@ -13,11 +13,11 @@ import (
// If any of the following fields are changed then the
// caller should Refresh the router.
type Route struct {
Name string `json:"name"` // "userRoute"
Method string `json:"method"` // "GET"
methodBckp string // if Method changed to something else (which is possible at runtime as well, via RefreshRouter) then this field will be filled with the old one.
Subdomain string `json:"subdomain"` // "admin."
tmpl *macro.Template // Tmpl().Src: "/api/user/{id:uint64}"
Name string `json:"name"` // "userRoute"
Method string `json:"method"` // "GET"
methodBckp string // if Method changed to something else (which is possible at runtime as well, via RefreshRouter) then this field will be filled with the old one.
Subdomain string `json:"subdomain"` // "admin."
tmpl macro.Template // Tmpl().Src: "/api/user/{id:uint64}"
// temp storage, they're appended to the Handlers on build.
// Execution happens before Handlers, can be empty.
beginHandlers context.Handlers
@ -50,7 +50,8 @@ func NewRoute(method, subdomain, unparsedPath, mainHandlerName string,
path := convertMacroTmplToNodePath(tmpl)
// prepend the macro handler to the route, now,
// right before the register to the tree, so APIBuilder#UseGlobal will work as expected.
if macroEvaluatorHandler, ok := handler.MakeHandler(tmpl); ok {
if handler.CanMakeHandler(tmpl) {
macroEvaluatorHandler := handler.MakeHandler(tmpl)
handlers = append(context.Handlers{macroEvaluatorHandler}, handlers...)
}
@ -155,7 +156,18 @@ func (r Route) String() string {
// via Tmpl().Src, Route.Path is the path
// converted to match the underline router's specs.
func (r Route) Tmpl() macro.Template {
return *r.tmpl
return r.tmpl
}
// RegisteredHandlersLen returns the end-developer's registered handlers, all except the macro evaluator handler
// if was required by the build process.
func (r Route) RegisteredHandlersLen() int {
n := len(r.Handlers)
if handler.CanMakeHandler(r.tmpl) {
n--
}
return n
}
// IsOnline returns true if the route is marked as "online" (state).
@ -245,7 +257,8 @@ func (r Route) Trace() string {
printfmt += fmt.Sprintf(" %s", r.Subdomain)
}
printfmt += fmt.Sprintf(" %s ", r.Tmpl().Src)
if l := len(r.Handlers); l > 1 {
if l := r.RegisteredHandlersLen(); l > 1 {
printfmt += fmt.Sprintf("-> %s() and %d more", r.MainHandlerName, l-1)
} else {
printfmt += fmt.Sprintf("-> %s()", r.MainHandlerName)

View File

@ -7,11 +7,11 @@ import (
"github.com/kataras/iris/macro"
)
// MakeHandler creates and returns a handler from a macro template, the handler evaluates each of the parameters if necessary at all.
// CanMakeHandler reports whether a macro template needs a special macro's evaluator handler to be validated
// before procceed to the next handler(s).
// If the template does not contain any dynamic attributes and a special handler is NOT required
// then it returns a nil handler and false as its second output value,
// the caller should check those two values before any further action.
func MakeHandler(tmpl *macro.Template) (handler context.Handler, needsMacroHandler bool) {
// then it returns false.
func CanMakeHandler(tmpl macro.Template) (needsMacroHandler bool) {
if len(tmpl.Params) == 0 {
return
}
@ -27,11 +27,18 @@ func MakeHandler(tmpl *macro.Template) (handler context.Handler, needsMacroHandl
}
}
if !needsMacroHandler {
return
return
}
// MakeHandler creates and returns a handler from a macro template, the handler evaluates each of the parameters if necessary at all.
// If the template does not contain any dynamic attributes and a special handler is NOT required
// then it returns a nil handler.
func MakeHandler(tmpl macro.Template) context.Handler {
if !CanMakeHandler(tmpl) {
return nil
}
handler = func(ctx context.Context) {
return func(ctx context.Context) {
for _, p := range tmpl.Params {
if !p.CanEval() {
continue // allow.
@ -46,6 +53,4 @@ func MakeHandler(tmpl *macro.Template) (handler context.Handler, needsMacroHandl
// if all passed, just continue.
ctx.Next()
}
return
}

View File

@ -6,7 +6,7 @@ import (
"github.com/kataras/iris/macro"
)
func TestMakeHandlerNeeds(t *testing.T) {
func TestCanMakeHandler(t *testing.T) {
tests := []struct {
src string
needsHandler bool
@ -29,13 +29,13 @@ func TestMakeHandlerNeeds(t *testing.T) {
if err != nil {
t.Fatalf("[%d] '%s' failed to be parsed: %v", i, tt.src, err)
}
if _, got := MakeHandler(tmpl); got != tt.needsHandler {
if got := CanMakeHandler(tmpl); got != tt.needsHandler {
if tt.needsHandler {
t.Fatalf("[%d] '%s' expected to be able to generate an evaluator handler instead of a nil one", i, tt.src)
} else {
t.Fatalf("[%d] '%s' should not need an evaluator handler", i, tt.src)
}
}
}
}

View File

@ -95,18 +95,17 @@ func (p *TemplateParam) Eval(paramValue string, paramChanger memstore.ValueSette
// and returns a new Template.
// It builds all the parameter functions for that template
// and their evaluators, it's the api call that makes use the interpeter's parser -> lexer.
func Parse(src string, macros Macros) (*Template, error) {
func Parse(src string, macros Macros) (Template, error) {
types := make([]ast.ParamType, len(macros))
for i, m := range macros {
types[i] = m
}
tmpl := Template{Src: src}
params, err := parser.Parse(src, types)
if err != nil {
return nil, err
return tmpl, err
}
t := new(Template)
t.Src = src
for idx, p := range params {
m := macros.Lookup(p.Type)
@ -140,8 +139,8 @@ func Parse(src string, macros Macros) (*Template, error) {
tmplParam.Funcs = append(tmplParam.Funcs, evalFn)
}
t.Params = append(t.Params, tmplParam.preComputed())
tmpl.Params = append(tmpl.Params, tmplParam.preComputed())
}
return t, nil
return tmpl, nil
}