Back to godoc.org

Package macro

v11.1.1+incompatible
Latest Go to latest

The latest major version is v12.

Published: Jan 16, 2019 | Licenses: BSD-3-Clause , BSD-3-Clause | Module: github.com/kataras/iris

Index

Variables

var (
	// String type
	// Allows anything (single path segment, as everything except the `Path`).
	// Its functions can be used by the rest of the macros and param types whenever not available function by name is used.
	// Because of its "master" boolean value to true (third parameter).
	String = NewMacro("string", "", true, false, nil).
			RegisterFunc("regexp", MustRegexp).
			RegisterFunc("prefix", func(prefix string) func(string) bool {
			return func(paramValue string) bool {
				return strings.HasPrefix(paramValue, prefix)
			}
		}).
		RegisterFunc("suffix", func(suffix string) func(string) bool {
			return func(paramValue string) bool {
				return strings.HasSuffix(paramValue, suffix)
			}
		}).
		RegisterFunc("contains", func(s string) func(string) bool {
			return func(paramValue string) bool {
				return strings.Contains(paramValue, s)
			}
		}).
		RegisterFunc("min", func(min int) func(string) bool {
			return func(paramValue string) bool {
				return len(paramValue) >= min
			}
		}).
		RegisterFunc("max", func(max int) func(string) bool {
			return func(paramValue string) bool {
				return max >= len(paramValue)
			}
		})

	// Int or number type
	// both positive and negative numbers, actual value can be min-max int64 or min-max int32 depends on the arch.
	// If x64: -9223372036854775808 to 9223372036854775807.
	// If x32: -2147483648 to 2147483647 and etc..
	Int = NewMacro("int", "number", false, false, func(paramValue string) (interface{}, bool) {
		if !simpleNumberEval(paramValue) {
			return nil, false
		}

		v, err := strconv.Atoi(paramValue)
		if err != nil {
			return nil, false
		}

		return v, true
	}).
		RegisterFunc("min", func(min int) func(int) bool {
			return func(paramValue int) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max int) func(int) bool {
			return func(paramValue int) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max int) func(int) bool {
			return func(paramValue int) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Int8 type
	// -128 to 127.
	Int8 = NewMacro("int8", "", false, false, func(paramValue string) (interface{}, bool) {
		if !simpleNumberEval(paramValue) {
			return nil, false
		}

		v, err := strconv.ParseInt(paramValue, 10, 8)
		if err != nil {
			return nil, false
		}
		return int8(v), true
	}).
		RegisterFunc("min", func(min int8) func(int8) bool {
			return func(paramValue int8) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max int8) func(int8) bool {
			return func(paramValue int8) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max int8) func(int8) bool {
			return func(paramValue int8) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Int16 type
	// -32768 to 32767.
	Int16 = NewMacro("int16", "", false, false, func(paramValue string) (interface{}, bool) {
		if !simpleNumberEval(paramValue) {
			return nil, false
		}

		v, err := strconv.ParseInt(paramValue, 10, 16)
		if err != nil {
			return nil, false
		}
		return int16(v), true
	}).
		RegisterFunc("min", func(min int16) func(int16) bool {
			return func(paramValue int16) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max int16) func(int16) bool {
			return func(paramValue int16) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max int16) func(int16) bool {
			return func(paramValue int16) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Int32 type
	// -2147483648 to 2147483647.
	Int32 = NewMacro("int32", "", false, false, func(paramValue string) (interface{}, bool) {
		if !simpleNumberEval(paramValue) {
			return nil, false
		}

		v, err := strconv.ParseInt(paramValue, 10, 32)
		if err != nil {
			return nil, false
		}
		return int32(v), true
	}).
		RegisterFunc("min", func(min int32) func(int32) bool {
			return func(paramValue int32) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max int32) func(int32) bool {
			return func(paramValue int32) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max int32) func(int32) bool {
			return func(paramValue int32) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Int64 as int64 type
	// -9223372036854775808 to 9223372036854775807.
	Int64 = NewMacro("int64", "long", false, false, func(paramValue string) (interface{}, bool) {
		if !simpleNumberEval(paramValue) {
			return nil, false
		}

		v, err := strconv.ParseInt(paramValue, 10, 64)
		if err != nil {
			return nil, false
		}
		return v, true
	}).
		RegisterFunc("min", func(min int64) func(int64) bool {
			return func(paramValue int64) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max int64) func(int64) bool {
			return func(paramValue int64) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max int64) func(int64) bool {
			return func(paramValue int64) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Uint as uint type
	// actual value can be min-max uint64 or min-max uint32 depends on the arch.
	// If x64: 0 to 18446744073709551615.
	// If x32: 0 to 4294967295 and etc.
	Uint = NewMacro("uint", "", false, false, func(paramValue string) (interface{}, bool) {
		v, err := strconv.ParseUint(paramValue, 10, strconv.IntSize)
		if err != nil {
			return nil, false
		}
		return uint(v), true
	}).
		RegisterFunc("min", func(min uint) func(uint) bool {
			return func(paramValue uint) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max uint) func(uint) bool {
			return func(paramValue uint) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max uint) func(uint) bool {
			return func(paramValue uint) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Uint8 as uint8 type
	// 0 to 255.
	Uint8 = NewMacro("uint8", "", false, false, func(paramValue string) (interface{}, bool) {
		if !uint8Eval(paramValue) {
			return nil, false
		}

		v, err := strconv.ParseUint(paramValue, 10, 8)
		if err != nil {
			return nil, false
		}
		return uint8(v), true
	}).
		RegisterFunc("min", func(min uint8) func(uint8) bool {
			return func(paramValue uint8) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max uint8) func(uint8) bool {
			return func(paramValue uint8) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max uint8) func(uint8) bool {
			return func(paramValue uint8) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Uint16 as uint16 type
	// 0 to 65535.
	Uint16 = NewMacro("uint16", "", false, false, func(paramValue string) (interface{}, bool) {
		v, err := strconv.ParseUint(paramValue, 10, 16)
		if err != nil {
			return nil, false
		}
		return uint16(v), true
	}).
		RegisterFunc("min", func(min uint16) func(uint16) bool {
			return func(paramValue uint16) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max uint16) func(uint16) bool {
			return func(paramValue uint16) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max uint16) func(uint16) bool {
			return func(paramValue uint16) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Uint32 as uint32 type
	// 0 to 4294967295.
	Uint32 = NewMacro("uint32", "", false, false, func(paramValue string) (interface{}, bool) {
		v, err := strconv.ParseUint(paramValue, 10, 32)
		if err != nil {
			return nil, false
		}
		return uint32(v), true
	}).
		RegisterFunc("min", func(min uint32) func(uint32) bool {
			return func(paramValue uint32) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max uint32) func(uint32) bool {
			return func(paramValue uint32) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max uint32) func(uint32) bool {
			return func(paramValue uint32) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Uint64 as uint64 type
	// 0 to 18446744073709551615.
	Uint64 = NewMacro("uint64", "", false, false, func(paramValue string) (interface{}, bool) {
		v, err := strconv.ParseUint(paramValue, 10, 64)
		if err != nil {
			return nil, false
		}
		return v, true
	}).
		RegisterFunc("min", func(min uint64) func(uint64) bool {
			return func(paramValue uint64) bool {
				return paramValue >= min
			}
		}).
		RegisterFunc("max", func(max uint64) func(uint64) bool {
			return func(paramValue uint64) bool {
				return paramValue <= max
			}
		}).
		RegisterFunc("range", func(min, max uint64) func(uint64) bool {
			return func(paramValue uint64) bool {
				return !(paramValue < min || paramValue > max)
			}
		})

	// Bool or boolean as bool type
	// a string which is "1" or "t" or "T" or "TRUE" or "true" or "True"
	// or "0" or "f" or "F" or "FALSE" or "false" or "False".
	Bool = NewMacro("bool", "boolean", false, false, func(paramValue string) (interface{}, bool) {

		v, err := strconv.ParseBool(paramValue)
		if err != nil {
			return nil, false
		}
		return v, true
	})

	// Alphabetical letter type
	// letters only (upper or lowercase)
	Alphabetical = NewMacro("alphabetical", "", false, false, func(paramValue string) (interface{}, bool) {
		if !alphabeticalEval(paramValue) {
			return nil, false
		}
		return paramValue, true
	})

	// File type
	// letters (upper or lowercase)
	// numbers (0-9)
	// underscore (_)
	// dash (-)
	// point (.)
	// no spaces! or other character
	File = NewMacro("file", "", false, false, func(paramValue string) (interface{}, bool) {
		if !fileEval(paramValue) {
			return nil, false
		}
		return paramValue, true
	})
	// Path type
	// anything, should be the last part
	//
	// It allows everything, we have String and Path as different
	// types because I want to give the opportunity to the user
	// to organise the macro functions based on wildcard or single dynamic named path parameter.
	// Should be living in the latest path segment of a route path.
	Path = NewMacro("path", "", false, true, nil)

	// Defaults contains the defaults macro and parameters types for the router.
	//
	// Read https://github.com/kataras/iris/tree/master/_examples/routing/macros for more details.
	Defaults = &Macros{
		String,
		Int,
		Int8,
		Int16,
		Int32,
		Int64,
		Uint,
		Uint8,
		Uint16,
		Uint32,
		Uint64,
		Bool,
		Alphabetical,
		Path,
	}
)

func MustRegexp

func MustRegexp(expr string) func(string) bool

MustRegexp same as Regexp but it panics on the "expr" parse failure.

func Regexp

func Regexp(expr string) (func(string) bool, error)

Regexp accepts a regexp "expr" expression and returns its MatchString. The regexp is compiled before return.

Returns a not-nil error on regexp compile failure.

type Macro

type Macro struct {
	Evaluator ParamEvaluator
	// contains filtered or unexported fields
}

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.

func NewMacro

func NewMacro(indent, alias string, master, trailing bool, evaluator ParamEvaluator) *Macro

NewMacro creates and returns a Macro that can be used as a registry for a new customized parameter type and its functions.

func (*Macro) Alias

func (m *Macro) Alias() string

Alias returns the alias of the parameter type, if any.

func (*Macro) Indent

func (m *Macro) Indent() string

Indent returns the name of the parameter type.

func (*Macro) Master

func (m *Macro) Master() bool

Master returns true if that macro's parameter type is the default one if not :type is followed by a parameter type inside the route path.

func (*Macro) RegisterFunc

func (m *Macro) RegisterFunc(funcName string, fn interface{}) *Macro

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 (*Macro) Trailing

func (m *Macro) Trailing() bool

Trailing returns true if that macro's parameter type is wildcard and can accept one or more path segments as one parameter value. A wildcard should be registered in the last path segment only.

type Macros

type Macros []*Macro

Macros is just a type of a slice of *Macro which is responsible to register and search for macros based on the indent(parameter type).

func (*Macros) Get

func (ms *Macros) Get(indentOrAlias string) *Macro

Get returns the responsible macro for a parameter type, it can return nil.

func (*Macros) GetMaster

func (ms *Macros) GetMaster() *Macro

GetMaster returns the default macro and its parameter type, by default it will return the `String` macro which is responsible for the "string" parameter type.

func (*Macros) GetTrailings

func (ms *Macros) GetTrailings() (macros []*Macro)

GetTrailings returns the macros that have support for wildcards parameter types. By default it will return the `Path` macro which is responsible for the "path" parameter type.

func (*Macros) Lookup

func (ms *Macros) Lookup(pt ast.ParamType) *Macro

Lookup returns the responsible macro for a parameter type, it can return nil.

func (*Macros) Register

func (ms *Macros) Register(indent, alias string, isMaster, isTrailing bool, evaluator ParamEvaluator) *Macro

Register registers a custom Macro. The "indent" should not be empty and should be unique, it is the parameter type's name, i.e "string". The "alias" is optionally and it should be unique, it is the alias of the parameter type. "isMaster" and "isTrailing" is for default parameter type and wildcard respectfully. The "evaluator" is the function that is converted to an Iris handler which is executed every time before the main chain of a route's handlers that contains this macro of the specific parameter type.

Read https://github.com/kataras/iris/tree/master/_examples/routing/macros for more details.

func (*Macros) Unregister

func (ms *Macros) Unregister(indent string) bool

Unregister removes a macro and its parameter type from the list.

type ParamEvaluator

type ParamEvaluator func(paramValue string) (interface{}, bool)

ParamEvaluator is the signature for param type evaluator. It accepts the param's value as string and returns the <T> value (which its type is used for the input argument of the parameter functions, if any) and a true value for passed, otherwise nil and false should be returned.

type ParamFunc

type ParamFunc struct {
	Name string
	Func ParamFuncBuilder
}

ParamFunc represents the parsed parameter function, it holds the parameter's name and the function which will build the evaluator func.

type ParamFuncBuilder

type ParamFuncBuilder func([]string) reflect.Value // the func(<T>) bool

ParamFuncBuilder is a func which accepts a param function's arguments (values) and returns a function as value, its job is to make the macros to be registered by user at the most generic possible way.

type Template

type Template struct {
	// Src is the original template given by the client
	Src    string          `json:"src"`
	Params []TemplateParam `json:"params"`
}

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.

func Parse

func Parse(src string, macros Macros) (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.

type TemplateParam

type TemplateParam struct {
	Src string `json:"src"` // the unparsed param'false source
	// Type is not useful anywhere here but maybe
	// it's useful on host to decide how to convert the path template to specific router's syntax
	Type          ast.ParamType   `json:"type"`
	Name          string          `json:"name"`
	Index         int             `json:"index"`
	ErrCode       int             `json:"errCode"`
	TypeEvaluator ParamEvaluator  `json:"-"`
	Funcs         []reflect.Value `json:"-"`
	// contains filtered or unexported fields
}

TemplateParam is the parsed macro parameter's template they are being used to describe the param's syntax result.

func (*TemplateParam) CanEval

func (p *TemplateParam) CanEval() bool

CanEval returns true if this "p" TemplateParam should be evaluated in serve time. It is computed before server ran and it is used to determinate if a route needs to build a macro handler (middleware).

func (*TemplateParam) Eval

func (p *TemplateParam) Eval(paramValue string, paramSetter memstore.ValueSetter) bool

Eval is the most critical part of the TEmplateParam. It is responsible to return "passed:true" or "not passed:false" if the "paramValue" is the correct type of the registered parameter type and all functions, if any, are passed. "paramChanger" is the same form of context's Params().Set we could accept a memstore.Store or even context.RequestParams but this form has been chosed in order to test easier and fully decoupled from a request when necessary.

It is called from the converted macro handler (middleware) from the higher-level component of "kataras/iris/macro/handler#MakeHandler".

Package Files

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier