1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-17 09:57:01 +00:00
Former-commit-id: 4e30bf6a74acb7d463c7fcf1e9e08ca3147117a7
This commit is contained in:
Gerasimos (Makis) Maropoulos
2017-10-06 08:23:03 +03:00
parent 4fb78bbcd9
commit e5600fcf0d
18 changed files with 682 additions and 419 deletions

View File

@@ -67,7 +67,6 @@ func (p *funcParser) parse() (*ast, error) {
}
if w == tokenBy {
typ := p.info.Type
funcArgPos++ // starting with 1 because in typ.NumIn() the first is the struct receiver.
// No need for these:
@@ -79,39 +78,10 @@ func (p *funcParser) parse() (*ast, error) {
// continue
// }
if typ.NumIn() <= funcArgPos {
// old:
// return nil, errors.New("keyword 'By' found but length of input receivers are not match for " +
// p.info.Name)
// By found but input arguments are not there, so act like /by path without restricts.
a.relPath += "/" + strings.ToLower(w)
continue
if err := p.parsePathParam(a, w, funcArgPos); err != nil {
return nil, err
}
var (
paramKey = genParamKey(funcArgPos) // paramfirst, paramsecond...
paramType = paramTypeString // default string
)
// string, int...
goType := typ.In(funcArgPos).Name()
if p.lexer.peekNext() == tokenWildcard {
p.lexer.skip() // skip the Wildcard word.
paramType = paramTypePath
} else if pType, ok := macroTypes[goType]; ok {
// it's not wildcard, so check base on our available macro types.
paramType = pType
} else {
return nil, errors.New("invalid syntax for " + p.info.Name)
}
a.paramKeys = append(a.paramKeys, paramKey)
a.paramTypes = append(a.paramTypes, paramType)
// /{paramfirst:path}, /{paramfirst:long}...
a.relPath += fmt.Sprintf("/{%s:%s}", paramKey, paramType)
a.dynamic = true
continue
}
@@ -120,6 +90,57 @@ func (p *funcParser) parse() (*ast, error) {
return a, nil
}
func (p *funcParser) parsePathParam(a *ast, w string, funcArgPos int) error {
typ := p.info.Type
if typ.NumIn() <= funcArgPos {
// old:
// return nil, errors.New("keyword 'By' found but length of input receivers are not match for " +
// p.info.Name)
// By found but input arguments are not there, so act like /by path without restricts.
a.relPath += "/" + strings.ToLower(w)
return nil
}
var (
paramKey = genParamKey(funcArgPos) // paramfirst, paramsecond...
paramType = paramTypeString // default string
)
// string, int...
goType := typ.In(funcArgPos).Name()
nextWord := p.lexer.peekNext()
if nextWord == tokenWildcard {
p.lexer.skip() // skip the Wildcard word.
paramType = paramTypePath
} else if pType, ok := macroTypes[goType]; ok {
// it's not wildcard, so check base on our available macro types.
paramType = pType
} else {
return errors.New("invalid syntax for " + p.info.Name)
}
a.paramKeys = append(a.paramKeys, paramKey)
a.paramTypes = append(a.paramTypes, paramType)
// /{paramfirst:path}, /{paramfirst:long}...
a.relPath += fmt.Sprintf("/{%s:%s}", paramKey, paramType)
a.dynamic = true
if nextWord == "" && typ.NumIn() > funcArgPos+1 {
// By is the latest word but func is expected
// more path parameters values, i.e:
// GetBy(name string, age int)
// The caller (parse) doesn't need to know
// about the incremental funcArgPos because
// it will not need it.
return p.parsePathParam(a, nextWord, funcArgPos+1)
}
return nil
}
type ast struct {
paramKeys []string // paramfirst, paramsecond... [0]
paramTypes []string // string, int, long, path... [0]

View File

@@ -221,6 +221,12 @@ func (c *Controller) Write(contents []byte) (int, error) {
return c.Ctx.ResponseWriter().Write(contents)
}
// Writef formats according to a format specifier and writes to the response.
func (c *Controller) Writef(format string, a ...interface{}) (int, error) {
c.tryWriteHeaders()
return c.Ctx.ResponseWriter().Writef(format, a...)
}
// BeginRequest starts the main controller
// it initialize the Ctx and other fields.
//

View File

@@ -446,18 +446,20 @@ func (c *testControllerRelPathFromFunc) EndRequest(ctx context.Context) {
c.Controller.EndRequest(ctx)
}
func (c *testControllerRelPathFromFunc) Get() {}
func (c *testControllerRelPathFromFunc) GetBy(int64) {}
func (c *testControllerRelPathFromFunc) GetByWildcard(string) {}
func (c *testControllerRelPathFromFunc) Get() {}
func (c *testControllerRelPathFromFunc) GetBy(int64) {}
func (c *testControllerRelPathFromFunc) GetAnythingByWildcard(string) {}
func (c *testControllerRelPathFromFunc) GetLogin() {}
func (c *testControllerRelPathFromFunc) PostLogin() {}
func (c *testControllerRelPathFromFunc) GetAdminLogin() {}
func (c *testControllerRelPathFromFunc) PutSomethingIntoThis() {}
func (c *testControllerRelPathFromFunc) PutSomethingIntoThis() {}
func (c *testControllerRelPathFromFunc) GetSomethingBy(bool) {}
func (c *testControllerRelPathFromFunc) GetSomethingByBy(string, int) {}
func (c *testControllerRelPathFromFunc) GetSomethingNewBy(string, int) {} // two input arguments, one By which is the latest word.
func (c *testControllerRelPathFromFunc) GetSomethingByElseThisBy(bool, int) {} // two input arguments
func TestControllerRelPathFromFunc(t *testing.T) {
@@ -478,6 +480,8 @@ func TestControllerRelPathFromFunc(t *testing.T) {
e.GET("/something/falsee").Expect().Status(httptest.StatusNotFound)
e.GET("/something/kataras/42").Expect().Status(httptest.StatusOK).
Body().Equal("GET:/something/kataras/42")
e.GET("/something/new/kataras/42").Expect().Status(httptest.StatusOK).
Body().Equal("GET:/something/new/kataras/42")
e.GET("/something/true/else/this/42").Expect().Status(httptest.StatusOK).
Body().Equal("GET:/something/true/else/this/42")