mirror of
https://github.com/kataras/iris.git
synced 2025-03-13 21:36:28 +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.
|
||||
type APIBuilder struct {
|
||||
// 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)
|
||||
errorCodeHandlers *ErrorCodeHandlers
|
||||
// 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
|
||||
// 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
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ import (
|
|||
|
||||
// defaultMacros returns a new macro map which
|
||||
// contains the default router's named param types functions.
|
||||
func defaultMacros() *macro.MacroMap {
|
||||
macros := macro.NewMacroMap()
|
||||
func defaultMacros() *macro.Map {
|
||||
macros := macro.NewMap()
|
||||
// registers the String and Int default macro funcs
|
||||
// user can add or override of his own funcs later on
|
||||
// i.e:
|
||||
|
@ -31,7 +31,7 @@ func defaultMacros() *macro.MacroMap {
|
|||
return macros
|
||||
}
|
||||
|
||||
func registerBuiltinsMacroFuncs(out *macro.MacroMap) {
|
||||
func registerBuiltinsMacroFuncs(out *macro.Map) {
|
||||
// register the String which is the default type if not
|
||||
// parameter type is specified or
|
||||
// if a given parameter into path given but the func doesn't exist on the
|
||||
|
|
|
@ -9,19 +9,39 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
// ParamType is a specific uint8 type
|
||||
// which holds the parameter types' type.
|
||||
type ParamType uint8
|
||||
|
||||
const (
|
||||
// ParamTypeUnExpected is an unexpected parameter type.
|
||||
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
|
||||
// /42
|
||||
// ParamTypeInt is the integer, a number type.
|
||||
// Allows only numbers (0-9)
|
||||
// Declaration: /mypath/{myparam:int}
|
||||
ParamTypeInt
|
||||
// /myparam
|
||||
// ParamTypeAlphabetical is the alphabetical/letter type type.
|
||||
// Allows letters only (upper or lowercase)
|
||||
// Declaration: /mypath/{myparam:alphabetical}
|
||||
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
|
||||
// /myparam1/myparam2
|
||||
// ParamTypePath is the multi path (or wildcard) type.
|
||||
// Allows anything, should be the last part
|
||||
// Declaration: /mypath/{myparam:path}
|
||||
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 {
|
||||
if typ, ok := paramTypes[ident]; ok {
|
||||
return typ
|
||||
|
@ -45,6 +73,14 @@ func LookupParamType(ident string) ParamType {
|
|||
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 {
|
||||
Src string // the original unparsed source, i.e: {id:int range(1,5) else 404}
|
||||
Name string // id
|
||||
|
@ -53,35 +89,11 @@ type ParamStatement struct {
|
|||
ErrorCode int // 404
|
||||
}
|
||||
|
||||
// ParamFuncArg represents a single parameter function's argument
|
||||
type ParamFuncArg interface{}
|
||||
|
||||
func ParamFuncArgInt64(a ParamFuncArg) (int64, bool) {
|
||||
if v, ok := a.(int64); ok {
|
||||
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
|
||||
}
|
||||
|
||||
// ParamFuncArgToInt converts and returns
|
||||
// any type of "a", to an integer.
|
||||
func ParamFuncArgToInt(a ParamFuncArg) (int, error) {
|
||||
switch a.(type) {
|
||||
case int:
|
||||
|
@ -95,26 +107,13 @@ func ParamFuncArgToInt(a ParamFuncArg) (int, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func ParamFuncArgString(a ParamFuncArg) (string, bool) {
|
||||
if v, ok := a.(string); ok {
|
||||
return v, false
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// ParamFunc holds the name of a parameter's function
|
||||
// and its arguments (values)
|
||||
// A param func is declared with:
|
||||
// {param:int range(1,5)},
|
||||
// the range is the
|
||||
// param function name
|
||||
// the 1 and 5 are the two param function arguments
|
||||
// range(1,5)
|
||||
type ParamFunc struct {
|
||||
Name string // range
|
||||
|
|
|
@ -14,6 +14,9 @@ import (
|
|||
"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) {
|
||||
pathParts := strings.SplitN(fullpath, "/", -1)
|
||||
p := new(ParamParser)
|
||||
|
@ -45,20 +48,27 @@ func Parse(fullpath string) ([]*ast.ParamStatement, error) {
|
|||
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 {
|
||||
src string
|
||||
errors []string
|
||||
}
|
||||
|
||||
// NewParamParser receives a "src" of a single parameter
|
||||
// and returns a new ParamParser, ready to Parse.
|
||||
func NewParamParser(src string) *ParamParser {
|
||||
p := new(ParamParser)
|
||||
p.Reset(src)
|
||||
return p
|
||||
}
|
||||
|
||||
// Reset resets this ParamParser,
|
||||
// reset the errors and set the source to the input "src".
|
||||
func (p *ParamParser) Reset(src string) {
|
||||
p.src = src
|
||||
|
||||
p.errors = []string{}
|
||||
}
|
||||
|
||||
|
@ -66,8 +76,15 @@ func (p *ParamParser) appendErr(format string, a ...interface{}) {
|
|||
p.errors = append(p.errors, fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
const DefaultParamErrorCode = 404
|
||||
const DefaultParamType = ast.ParamTypeString
|
||||
const (
|
||||
// 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) {
|
||||
if t.Type == token.INT {
|
||||
|
@ -83,6 +100,8 @@ func (p ParamParser) Error() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Parse parses the p.src and returns its param statement
|
||||
// and an error on failure.
|
||||
func (p *ParamParser) Parse() (*ast.ParamStatement, error) {
|
||||
l := lexer.New(p.src)
|
||||
|
||||
|
|
|
@ -129,7 +129,8 @@ func TestParseParam(t *testing.T) {
|
|||
}}, // 7
|
||||
|
||||
}
|
||||
var p *ParamParser = new(ParamParser)
|
||||
|
||||
p := new(ParamParser)
|
||||
for i, tt := range tests {
|
||||
p.Reset(tt.expectedStatement.Src)
|
||||
resultStmt, err := p.Parse()
|
||||
|
|
|
@ -13,9 +13,16 @@ import (
|
|||
"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
|
||||
|
||||
// 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) {
|
||||
if expr == "" {
|
||||
return nil, fmt.Errorf("empty regex expression")
|
||||
|
@ -34,6 +41,8 @@ func NewEvaluatorFromRegexp(expr string) (EvaluatorFunc, error) {
|
|||
return r.MatchString, nil
|
||||
}
|
||||
|
||||
// MustNewEvaluatorFromRegexp same as NewEvaluatorFromRegexp
|
||||
// but it panics on the "expr" parse failure.
|
||||
func MustNewEvaluatorFromRegexp(expr string) EvaluatorFunc {
|
||||
r, err := NewEvaluatorFromRegexp(expr)
|
||||
if err != nil {
|
||||
|
@ -122,13 +131,34 @@ func convertBuilderFunc(fn interface{}) ParamEvaluatorBuilder {
|
|||
}
|
||||
|
||||
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 {
|
||||
Evaluator EvaluatorFunc
|
||||
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
|
||||
|
||||
// ParamFunc represents the parsed
|
||||
// parameter function, it holds
|
||||
// the parameter's name
|
||||
// and the function which will build
|
||||
// the evaluator func.
|
||||
ParamFunc struct {
|
||||
Name string
|
||||
Func ParamEvaluatorBuilder
|
||||
|
@ -139,7 +169,12 @@ func newMacro(evaluator EvaluatorFunc) *Macro {
|
|||
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{}) {
|
||||
fullFn := convertBuilderFunc(fn)
|
||||
m.registerFunc(funcName, fullFn)
|
||||
|
@ -175,7 +210,10 @@ func (m *Macro) getFunc(funcName string) ParamEvaluatorBuilder {
|
|||
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
|
||||
// anything
|
||||
String *Macro
|
||||
|
@ -198,8 +236,12 @@ type MacroMap struct {
|
|||
Path *Macro
|
||||
}
|
||||
|
||||
func NewMacroMap() *MacroMap {
|
||||
return &MacroMap{
|
||||
// NewMap returns a new macro Map with default
|
||||
// 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.
|
||||
String: newMacro(func(string) bool { return true }),
|
||||
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 {
|
||||
case ast.ParamTypeInt:
|
||||
return m.Int
|
||||
|
|
|
@ -9,12 +9,20 @@ import (
|
|||
"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 {
|
||||
// Src is the original template given by the client
|
||||
Src string
|
||||
Params []TemplateParam
|
||||
}
|
||||
|
||||
// TemplateParam is the parsed macro parameter's template
|
||||
// they are being used to describe the param's syntax result.
|
||||
type TemplateParam struct {
|
||||
Src string // the unparsed param'false source
|
||||
// Type is not useful anywhere here but maybe
|
||||
|
@ -26,7 +34,11 @@ type TemplateParam struct {
|
|||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -33,7 +33,7 @@ type Route struct {
|
|||
// It parses the path based on the "macros",
|
||||
// handlers are being changed to validate the macros at serve time, if needed.
|
||||
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)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue
Block a user