mirror of
https://github.com/kataras/iris.git
synced 2025-03-15 17:36:29 +01:00
Linting 🅰️
Former-commit-id: 367bb53ed6656002c60c40e3ad30bda578de21c6
This commit is contained in:
parent
74989ad0a1
commit
fb85ae15d5
|
@ -73,7 +73,7 @@ type RoutesProvider interface { // api builder
|
||||||
// and child routers.
|
// and child routers.
|
||||||
type APIBuilder struct {
|
type APIBuilder struct {
|
||||||
// the api builder global macros registry
|
// the api builder global macros registry
|
||||||
macros *macro.MacroMap
|
macros *macro.Map
|
||||||
// the api builder global handlers per status code registry (used for custom http errors)
|
// the api builder global handlers per status code registry (used for custom http errors)
|
||||||
errorCodeHandlers *ErrorCodeHandlers
|
errorCodeHandlers *ErrorCodeHandlers
|
||||||
// the api builder global routes repository
|
// the api builder global routes repository
|
||||||
|
@ -181,7 +181,9 @@ func (rb *APIBuilder) Party(relativePath string, handlers ...context.Handler) Pa
|
||||||
|
|
||||||
// Macros returns the macro map which is responsible
|
// Macros returns the macro map which is responsible
|
||||||
// to register custom macro functions for all routes.
|
// to register custom macro functions for all routes.
|
||||||
func (rb *APIBuilder) Macros() *macro.MacroMap {
|
//
|
||||||
|
// Learn more at: https://github.com/kataras/iris/tree/master/_examples/beginner/routing/dynamic-path
|
||||||
|
func (rb *APIBuilder) Macros() *macro.Map {
|
||||||
return rb.macros
|
return rb.macros
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,8 @@ import (
|
||||||
|
|
||||||
// defaultMacros returns a new macro map which
|
// defaultMacros returns a new macro map which
|
||||||
// contains the default router's named param types functions.
|
// contains the default router's named param types functions.
|
||||||
func defaultMacros() *macro.MacroMap {
|
func defaultMacros() *macro.Map {
|
||||||
macros := macro.NewMacroMap()
|
macros := macro.NewMap()
|
||||||
// registers the String and Int default macro funcs
|
// registers the String and Int default macro funcs
|
||||||
// user can add or override of his own funcs later on
|
// user can add or override of his own funcs later on
|
||||||
// i.e:
|
// i.e:
|
||||||
|
@ -31,7 +31,7 @@ func defaultMacros() *macro.MacroMap {
|
||||||
return macros
|
return macros
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerBuiltinsMacroFuncs(out *macro.MacroMap) {
|
func registerBuiltinsMacroFuncs(out *macro.Map) {
|
||||||
// register the String which is the default type if not
|
// register the String which is the default type if not
|
||||||
// parameter type is specified or
|
// parameter type is specified or
|
||||||
// if a given parameter into path given but the func doesn't exist on the
|
// if a given parameter into path given but the func doesn't exist on the
|
||||||
|
|
|
@ -9,19 +9,39 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ParamType is a specific uint8 type
|
||||||
|
// which holds the parameter types' type.
|
||||||
type ParamType uint8
|
type ParamType uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// ParamTypeUnExpected is an unexpected parameter type.
|
||||||
ParamTypeUnExpected ParamType = iota
|
ParamTypeUnExpected ParamType = iota
|
||||||
// /myparam1
|
// ParamTypeString is the string type.
|
||||||
|
// If parameter type is missing then it defaults to String type.
|
||||||
|
// Allows anything
|
||||||
|
// Declaration: /mypath/{myparam:string} or /mypath{myparam}
|
||||||
ParamTypeString
|
ParamTypeString
|
||||||
// /42
|
// ParamTypeInt is the integer, a number type.
|
||||||
|
// Allows only numbers (0-9)
|
||||||
|
// Declaration: /mypath/{myparam:int}
|
||||||
ParamTypeInt
|
ParamTypeInt
|
||||||
// /myparam
|
// ParamTypeAlphabetical is the alphabetical/letter type type.
|
||||||
|
// Allows letters only (upper or lowercase)
|
||||||
|
// Declaration: /mypath/{myparam:alphabetical}
|
||||||
ParamTypeAlphabetical
|
ParamTypeAlphabetical
|
||||||
// /main.css
|
// ParamTypeFile is the file single path type.
|
||||||
|
// Allows:
|
||||||
|
// letters (upper or lowercase)
|
||||||
|
// numbers (0-9)
|
||||||
|
// underscore (_)
|
||||||
|
// dash (-)
|
||||||
|
// point (.)
|
||||||
|
// no spaces! or other character
|
||||||
|
// Declaration: /mypath/{myparam:file}
|
||||||
ParamTypeFile
|
ParamTypeFile
|
||||||
// /myparam1/myparam2
|
// ParamTypePath is the multi path (or wildcard) type.
|
||||||
|
// Allows anything, should be the last part
|
||||||
|
// Declaration: /mypath/{myparam:path}
|
||||||
ParamTypePath
|
ParamTypePath
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,6 +58,14 @@ var paramTypes = map[string]ParamType{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LookupParamType accepts the string
|
||||||
|
// representation of a parameter type.
|
||||||
|
// Available:
|
||||||
|
// "string"
|
||||||
|
// "int"
|
||||||
|
// "alphabetical"
|
||||||
|
// "file"
|
||||||
|
// "path"
|
||||||
func LookupParamType(ident string) ParamType {
|
func LookupParamType(ident string) ParamType {
|
||||||
if typ, ok := paramTypes[ident]; ok {
|
if typ, ok := paramTypes[ident]; ok {
|
||||||
return typ
|
return typ
|
||||||
|
@ -45,6 +73,14 @@ func LookupParamType(ident string) ParamType {
|
||||||
return ParamTypeUnExpected
|
return ParamTypeUnExpected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParamStatement is a struct
|
||||||
|
// which holds all the necessary information about a macro parameter.
|
||||||
|
// It holds its type (string, int, alphabetical, file, path),
|
||||||
|
// its source ({param:type}),
|
||||||
|
// its name ("param"),
|
||||||
|
// its attached functions by the user (min, max...)
|
||||||
|
// and the http error code if that parameter
|
||||||
|
// failed to be evaluated.
|
||||||
type ParamStatement struct {
|
type ParamStatement struct {
|
||||||
Src string // the original unparsed source, i.e: {id:int range(1,5) else 404}
|
Src string // the original unparsed source, i.e: {id:int range(1,5) else 404}
|
||||||
Name string // id
|
Name string // id
|
||||||
|
@ -53,35 +89,11 @@ type ParamStatement struct {
|
||||||
ErrorCode int // 404
|
ErrorCode int // 404
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParamFuncArg represents a single parameter function's argument
|
||||||
type ParamFuncArg interface{}
|
type ParamFuncArg interface{}
|
||||||
|
|
||||||
func ParamFuncArgInt64(a ParamFuncArg) (int64, bool) {
|
// ParamFuncArgToInt converts and returns
|
||||||
if v, ok := a.(int64); ok {
|
// any type of "a", to an integer.
|
||||||
return v, false
|
|
||||||
}
|
|
||||||
return -1, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParamFuncArgToInt64(a ParamFuncArg) (int64, error) {
|
|
||||||
switch a.(type) {
|
|
||||||
case int64:
|
|
||||||
return a.(int64), nil
|
|
||||||
case string:
|
|
||||||
return strconv.ParseInt(a.(string), 10, 64)
|
|
||||||
case int:
|
|
||||||
return int64(a.(int)), nil
|
|
||||||
default:
|
|
||||||
return -1, fmt.Errorf("unexpected function argument type: %q", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParamFuncArgInt(a ParamFuncArg) (int, bool) {
|
|
||||||
if v, ok := a.(int); ok {
|
|
||||||
return v, false
|
|
||||||
}
|
|
||||||
return -1, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParamFuncArgToInt(a ParamFuncArg) (int, error) {
|
func ParamFuncArgToInt(a ParamFuncArg) (int, error) {
|
||||||
switch a.(type) {
|
switch a.(type) {
|
||||||
case int:
|
case int:
|
||||||
|
@ -95,26 +107,13 @@ func ParamFuncArgToInt(a ParamFuncArg) (int, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParamFuncArgString(a ParamFuncArg) (string, bool) {
|
// ParamFunc holds the name of a parameter's function
|
||||||
if v, ok := a.(string); ok {
|
// and its arguments (values)
|
||||||
return v, false
|
// A param func is declared with:
|
||||||
}
|
// {param:int range(1,5)},
|
||||||
return "", false
|
// the range is the
|
||||||
}
|
// param function name
|
||||||
|
// the 1 and 5 are the two param function arguments
|
||||||
func ParamFuncArgToString(a ParamFuncArg) (string, error) {
|
|
||||||
switch a.(type) {
|
|
||||||
case string:
|
|
||||||
return a.(string), nil
|
|
||||||
case int:
|
|
||||||
return strconv.Itoa(a.(int)), nil
|
|
||||||
case int64:
|
|
||||||
return strconv.FormatInt(a.(int64), 10), nil
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("unexpected function argument type: %q", a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// range(1,5)
|
// range(1,5)
|
||||||
type ParamFunc struct {
|
type ParamFunc struct {
|
||||||
Name string // range
|
Name string // range
|
||||||
|
|
|
@ -14,6 +14,9 @@ import (
|
||||||
"github.com/kataras/iris/core/router/macro/interpreter/token"
|
"github.com/kataras/iris/core/router/macro/interpreter/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Parse takes a route "fullpath"
|
||||||
|
// and returns its param statements
|
||||||
|
// and an error on failure.
|
||||||
func Parse(fullpath string) ([]*ast.ParamStatement, error) {
|
func Parse(fullpath string) ([]*ast.ParamStatement, error) {
|
||||||
pathParts := strings.SplitN(fullpath, "/", -1)
|
pathParts := strings.SplitN(fullpath, "/", -1)
|
||||||
p := new(ParamParser)
|
p := new(ParamParser)
|
||||||
|
@ -45,20 +48,27 @@ func Parse(fullpath string) ([]*ast.ParamStatement, error) {
|
||||||
return statements, nil
|
return statements, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParamParser is the parser
|
||||||
|
// which is being used by the Parse function
|
||||||
|
// to parse path segments one by one
|
||||||
|
// and return their parsed parameter statements (param name, param type its functions and the inline route's functions).
|
||||||
type ParamParser struct {
|
type ParamParser struct {
|
||||||
src string
|
src string
|
||||||
errors []string
|
errors []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewParamParser receives a "src" of a single parameter
|
||||||
|
// and returns a new ParamParser, ready to Parse.
|
||||||
func NewParamParser(src string) *ParamParser {
|
func NewParamParser(src string) *ParamParser {
|
||||||
p := new(ParamParser)
|
p := new(ParamParser)
|
||||||
p.Reset(src)
|
p.Reset(src)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset resets this ParamParser,
|
||||||
|
// reset the errors and set the source to the input "src".
|
||||||
func (p *ParamParser) Reset(src string) {
|
func (p *ParamParser) Reset(src string) {
|
||||||
p.src = src
|
p.src = src
|
||||||
|
|
||||||
p.errors = []string{}
|
p.errors = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,8 +76,15 @@ func (p *ParamParser) appendErr(format string, a ...interface{}) {
|
||||||
p.errors = append(p.errors, fmt.Sprintf(format, a...))
|
p.errors = append(p.errors, fmt.Sprintf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
||||||
const DefaultParamErrorCode = 404
|
const (
|
||||||
const DefaultParamType = ast.ParamTypeString
|
// DefaultParamErrorCode is the default http error code, 404 not found,
|
||||||
|
// per-parameter. An error code can be setted via
|
||||||
|
// the "else" keyword inside a route's path.
|
||||||
|
DefaultParamErrorCode = 404
|
||||||
|
// DefaultParamType when parameter type is missing use this param type, defaults to string
|
||||||
|
// and it should be remains unless earth split in two.
|
||||||
|
DefaultParamType = ast.ParamTypeString
|
||||||
|
)
|
||||||
|
|
||||||
func parseParamFuncArg(t token.Token) (a ast.ParamFuncArg, err error) {
|
func parseParamFuncArg(t token.Token) (a ast.ParamFuncArg, err error) {
|
||||||
if t.Type == token.INT {
|
if t.Type == token.INT {
|
||||||
|
@ -83,6 +100,8 @@ func (p ParamParser) Error() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse parses the p.src and returns its param statement
|
||||||
|
// and an error on failure.
|
||||||
func (p *ParamParser) Parse() (*ast.ParamStatement, error) {
|
func (p *ParamParser) Parse() (*ast.ParamStatement, error) {
|
||||||
l := lexer.New(p.src)
|
l := lexer.New(p.src)
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,8 @@ func TestParseParam(t *testing.T) {
|
||||||
}}, // 7
|
}}, // 7
|
||||||
|
|
||||||
}
|
}
|
||||||
var p *ParamParser = new(ParamParser)
|
|
||||||
|
p := new(ParamParser)
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
p.Reset(tt.expectedStatement.Src)
|
p.Reset(tt.expectedStatement.Src)
|
||||||
resultStmt, err := p.Parse()
|
resultStmt, err := p.Parse()
|
||||||
|
|
|
@ -13,9 +13,16 @@ import (
|
||||||
"github.com/kataras/iris/core/router/macro/interpreter/ast"
|
"github.com/kataras/iris/core/router/macro/interpreter/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
// final evaluator signature for both param types and param funcs
|
// EvaluatorFunc is the signature for both param types and param funcs.
|
||||||
|
// It should accepts the param's value as string
|
||||||
|
// and return true if validated otherwise false.
|
||||||
type EvaluatorFunc func(paramValue string) bool
|
type EvaluatorFunc func(paramValue string) bool
|
||||||
|
|
||||||
|
// NewEvaluatorFromRegexp accepts a regexp "expr" expression
|
||||||
|
// and returns an EvaluatorFunc based on that regexp.
|
||||||
|
// the regexp is compiled before return.
|
||||||
|
//
|
||||||
|
// Returns a not-nil error on regexp compile failure.
|
||||||
func NewEvaluatorFromRegexp(expr string) (EvaluatorFunc, error) {
|
func NewEvaluatorFromRegexp(expr string) (EvaluatorFunc, error) {
|
||||||
if expr == "" {
|
if expr == "" {
|
||||||
return nil, fmt.Errorf("empty regex expression")
|
return nil, fmt.Errorf("empty regex expression")
|
||||||
|
@ -34,6 +41,8 @@ func NewEvaluatorFromRegexp(expr string) (EvaluatorFunc, error) {
|
||||||
return r.MatchString, nil
|
return r.MatchString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustNewEvaluatorFromRegexp same as NewEvaluatorFromRegexp
|
||||||
|
// but it panics on the "expr" parse failure.
|
||||||
func MustNewEvaluatorFromRegexp(expr string) EvaluatorFunc {
|
func MustNewEvaluatorFromRegexp(expr string) EvaluatorFunc {
|
||||||
r, err := NewEvaluatorFromRegexp(expr)
|
r, err := NewEvaluatorFromRegexp(expr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -122,13 +131,34 @@ func convertBuilderFunc(fn interface{}) ParamEvaluatorBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// Macro represents the parsed macro,
|
||||||
|
// which holds
|
||||||
|
// the evaluator (param type's evaluator + param functions evaluators)
|
||||||
|
// and its param functions.
|
||||||
|
//
|
||||||
|
// Any type contains its own macro
|
||||||
|
// instance, so an String type
|
||||||
|
// contains its type evaluator
|
||||||
|
// which is the "Evaluator" field
|
||||||
|
// and it can register param functions
|
||||||
|
// to that macro which maps to a parameter type.
|
||||||
Macro struct {
|
Macro struct {
|
||||||
Evaluator EvaluatorFunc
|
Evaluator EvaluatorFunc
|
||||||
funcs []ParamFunc
|
funcs []ParamFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParamEvaluatorBuilder is a func
|
||||||
|
// which accepts a param function's arguments (values)
|
||||||
|
// and returns an EvaluatorFunc, its job
|
||||||
|
// is to make the macros to be registered
|
||||||
|
// by user at the most generic possible way.
|
||||||
ParamEvaluatorBuilder func([]ast.ParamFuncArg) EvaluatorFunc
|
ParamEvaluatorBuilder func([]ast.ParamFuncArg) EvaluatorFunc
|
||||||
|
|
||||||
|
// ParamFunc represents the parsed
|
||||||
|
// parameter function, it holds
|
||||||
|
// the parameter's name
|
||||||
|
// and the function which will build
|
||||||
|
// the evaluator func.
|
||||||
ParamFunc struct {
|
ParamFunc struct {
|
||||||
Name string
|
Name string
|
||||||
Func ParamEvaluatorBuilder
|
Func ParamEvaluatorBuilder
|
||||||
|
@ -139,7 +169,12 @@ func newMacro(evaluator EvaluatorFunc) *Macro {
|
||||||
return &Macro{Evaluator: evaluator}
|
return &Macro{Evaluator: evaluator}
|
||||||
}
|
}
|
||||||
|
|
||||||
// at boot time, per param
|
// RegisterFunc registers a parameter function
|
||||||
|
// to that macro.
|
||||||
|
// Accepts the func name ("range")
|
||||||
|
// and the function body, which should return an EvaluatorFunc
|
||||||
|
// a bool (it will be converted to EvaluatorFunc later on),
|
||||||
|
// i.e RegisterFunc("min", func(minValue int) func(paramValue string) bool){})
|
||||||
func (m *Macro) RegisterFunc(funcName string, fn interface{}) {
|
func (m *Macro) RegisterFunc(funcName string, fn interface{}) {
|
||||||
fullFn := convertBuilderFunc(fn)
|
fullFn := convertBuilderFunc(fn)
|
||||||
m.registerFunc(funcName, fullFn)
|
m.registerFunc(funcName, fullFn)
|
||||||
|
@ -175,7 +210,10 @@ func (m *Macro) getFunc(funcName string) ParamEvaluatorBuilder {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type MacroMap struct {
|
// Map contains the default macros mapped to their types.
|
||||||
|
// This is the manager which is used by the caller to register custom
|
||||||
|
// parameter functions per param-type (String, Int, Alphabetical, File, Path).
|
||||||
|
type Map struct {
|
||||||
// string type
|
// string type
|
||||||
// anything
|
// anything
|
||||||
String *Macro
|
String *Macro
|
||||||
|
@ -198,8 +236,12 @@ type MacroMap struct {
|
||||||
Path *Macro
|
Path *Macro
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMacroMap() *MacroMap {
|
// NewMap returns a new macro Map with default
|
||||||
return &MacroMap{
|
// type evaluators.
|
||||||
|
//
|
||||||
|
// Learn more at: https://github.com/kataras/iris/tree/master/_examples/beginner/routing/dynamic-path
|
||||||
|
func NewMap() *Map {
|
||||||
|
return &Map{
|
||||||
// it allows everything, so no need for a regexp here.
|
// it allows everything, so no need for a regexp here.
|
||||||
String: newMacro(func(string) bool { return true }),
|
String: newMacro(func(string) bool { return true }),
|
||||||
Int: newMacro(MustNewEvaluatorFromRegexp("^[0-9]+$")),
|
Int: newMacro(MustNewEvaluatorFromRegexp("^[0-9]+$")),
|
||||||
|
@ -213,7 +255,11 @@ func NewMacroMap() *MacroMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MacroMap) Lookup(typ ast.ParamType) *Macro {
|
// Lookup returns the specific Macro from the map
|
||||||
|
// based on the parameter type.
|
||||||
|
// i.e if ast.ParamTypeInt then it will return the m.Int.
|
||||||
|
// Returns the m.String if not matched.
|
||||||
|
func (m *Map) Lookup(typ ast.ParamType) *Macro {
|
||||||
switch typ {
|
switch typ {
|
||||||
case ast.ParamTypeInt:
|
case ast.ParamTypeInt:
|
||||||
return m.Int
|
return m.Int
|
||||||
|
|
|
@ -9,12 +9,20 @@ import (
|
||||||
"github.com/kataras/iris/core/router/macro/interpreter/parser"
|
"github.com/kataras/iris/core/router/macro/interpreter/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Template contains a route's path full parsed template.
|
||||||
|
//
|
||||||
|
// Fields:
|
||||||
|
// Src is the raw source of the path, i.e /users/{id:int min(1)}
|
||||||
|
// Params is the list of the Params that are being used to the
|
||||||
|
// path, i.e the min as param name and 1 as the param argument.
|
||||||
type Template struct {
|
type Template struct {
|
||||||
// Src is the original template given by the client
|
// Src is the original template given by the client
|
||||||
Src string
|
Src string
|
||||||
Params []TemplateParam
|
Params []TemplateParam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TemplateParam is the parsed macro parameter's template
|
||||||
|
// they are being used to describe the param's syntax result.
|
||||||
type TemplateParam struct {
|
type TemplateParam struct {
|
||||||
Src string // the unparsed param'false source
|
Src string // the unparsed param'false source
|
||||||
// Type is not useful anywhere here but maybe
|
// Type is not useful anywhere here but maybe
|
||||||
|
@ -26,7 +34,11 @@ type TemplateParam struct {
|
||||||
Funcs []EvaluatorFunc
|
Funcs []EvaluatorFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func Parse(src string, macros *MacroMap) (*Template, error) {
|
// Parse takes a full route path and a macro map (macro map contains the macro types with their registered param functions)
|
||||||
|
// 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 *Map) (*Template, error) {
|
||||||
params, err := parser.Parse(src)
|
params, err := parser.Parse(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -33,7 +33,7 @@ type Route struct {
|
||||||
// It parses the path based on the "macros",
|
// It parses the path based on the "macros",
|
||||||
// handlers are being changed to validate the macros at serve time, if needed.
|
// handlers are being changed to validate the macros at serve time, if needed.
|
||||||
func NewRoute(method, subdomain, unparsedPath string,
|
func NewRoute(method, subdomain, unparsedPath string,
|
||||||
handlers context.Handlers, macros *macro.MacroMap) (*Route, error) {
|
handlers context.Handlers, macros *macro.Map) (*Route, error) {
|
||||||
|
|
||||||
tmpl, err := macro.Parse(unparsedPath, macros)
|
tmpl, err := macro.Parse(unparsedPath, macros)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user