mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 23:40:35 +01:00
add uint8 parameter type, and mvc and hero - this commit may be a point of tutorial on how to add a completely new type from scratch to the hero for future contributors
Former-commit-id: dc7a7e6c97ef0c644a22e92072e4bdb98ae10582
This commit is contained in:
parent
ef5f383227
commit
cbd8fe95ac
|
@ -166,6 +166,12 @@ both positive and negative numbers, any number of digits (ctx.Params().GetInt wi
|
|||
int64 type
|
||||
-9223372036854775808 to 9223372036854775807
|
||||
|
||||
+------------------------+
|
||||
| {param:uint8} |
|
||||
+------------------------+
|
||||
uint8 type
|
||||
0 to 255
|
||||
|
||||
+------------------------+
|
||||
| {param:uint64} |
|
||||
+------------------------+
|
||||
|
|
|
@ -48,6 +48,13 @@ func main() {
|
|||
// -9223372036854775808 to 9223372036854775807
|
||||
//
|
||||
// +------------------------+
|
||||
// | {param:uint8} |
|
||||
// +------------------------+
|
||||
// uint8 type
|
||||
// 0 to 255
|
||||
//
|
||||
//
|
||||
// +------------------------+
|
||||
// | {param:uint64} |
|
||||
// +------------------------+
|
||||
// uint64 type
|
||||
|
@ -146,6 +153,12 @@ func main() {
|
|||
ctx.Writef("Hello id: %d looking for friend id: ", id, friendid)
|
||||
}) // this will throw e 504 error code instead of 404 if all route's macros not passed.
|
||||
|
||||
// :uint8 0 to 255.
|
||||
app.Get("/ages/{age:uint8 else 400}", func(ctx iris.Context) {
|
||||
age, _ := ctx.Params().GetUint8("age")
|
||||
ctx.Writef("age selected: %d", age)
|
||||
})
|
||||
|
||||
// Another example using a custom regexp and any custom logic.
|
||||
latLonExpr := "^-?[0-9]{1,3}(?:\\.[0-9]{1,10})?$"
|
||||
latLonRegex, err := regexp.Compile(latLonExpr)
|
||||
|
|
|
@ -162,7 +162,14 @@ func (r RequestParams) GetFloat64(key string) (float64, error) {
|
|||
return r.store.GetFloat64(key)
|
||||
}
|
||||
|
||||
// GetUint64 returns the path paramete's value as uint64, based on its key.
|
||||
// GetUint8 returns the path parameter's value as uint8, based on its key.
|
||||
// It checks for all available types of int, including int, string.
|
||||
// It will return 0 and a non-nil error if parameter wasn't found.
|
||||
func (r RequestParams) GetUint8(key string) (uint8, error) {
|
||||
return r.store.GetUint8(key)
|
||||
}
|
||||
|
||||
// GetUint64 returns the path parameter's value as uint64, based on its key.
|
||||
// It checks for all available types of int, including int, uint64, int64, strings etc.
|
||||
// It will return 0 and a non-nil error if parameter wasn't found.
|
||||
func (r RequestParams) GetUint64(key string) (uint64, error) {
|
||||
|
|
|
@ -197,6 +197,39 @@ func (e Entry) Float32Default(key string, def float32) (float32, error) {
|
|||
return def, errFindParse.Format("float32", e.Key)
|
||||
}
|
||||
|
||||
// Uint8Default returns the entry's value as uint8.
|
||||
// If not found returns "def" and a non-nil error.
|
||||
func (e Entry) Uint8Default(def uint8) (uint8, error) {
|
||||
v := e.ValueRaw
|
||||
if v == nil {
|
||||
return def, errFindParse.Format("uint8", e.Key)
|
||||
}
|
||||
|
||||
if vuint8, ok := v.(uint8); ok {
|
||||
return vuint8, nil
|
||||
}
|
||||
|
||||
if vint, ok := v.(int); ok {
|
||||
if vint < 0 || vint > 255 {
|
||||
return def, errFindParse.Format("uint8", e.Key)
|
||||
}
|
||||
return uint8(vint), nil
|
||||
}
|
||||
|
||||
if vstring, sok := v.(string); sok {
|
||||
vuint64, err := strconv.ParseUint(vstring, 10, 8)
|
||||
if err != nil {
|
||||
return def, err
|
||||
}
|
||||
if vuint64 > 255 {
|
||||
return def, errFindParse.Format("uint8", e.Key)
|
||||
}
|
||||
return uint8(vuint64), nil
|
||||
}
|
||||
|
||||
return def, errFindParse.Format("uint8", e.Key)
|
||||
}
|
||||
|
||||
// Uint64Default returns the entry's value as uint64.
|
||||
// If not found returns "def" and a non-nil error.
|
||||
func (e Entry) Uint64Default(def uint64) (uint64, error) {
|
||||
|
@ -449,6 +482,26 @@ func (r *Store) GetIntDefault(key string, def int) int {
|
|||
return def
|
||||
}
|
||||
|
||||
// GetUint8 returns the entry's value as uint8, based on its key.
|
||||
// If not found returns 0 and a non-nil error.
|
||||
func (r *Store) GetUint8(key string) (uint8, error) {
|
||||
v := r.GetEntry(key)
|
||||
if v == nil {
|
||||
return 0, errFindParse.Format("uint8", key)
|
||||
}
|
||||
return v.Uint8Default(0)
|
||||
}
|
||||
|
||||
// GetUint8Default returns the entry's value as uint8, based on its key.
|
||||
// If not found returns "def".
|
||||
func (r *Store) GetUint8Default(key string, def uint8) uint8 {
|
||||
if v, err := r.GetUint8(key); err == nil {
|
||||
return v
|
||||
}
|
||||
|
||||
return def
|
||||
}
|
||||
|
||||
// GetUint64 returns the entry's value as uint64, based on its key.
|
||||
// If not found returns 0 and a non-nil error.
|
||||
func (r *Store) GetUint64(key string) (uint64, error) {
|
||||
|
|
|
@ -37,6 +37,7 @@ func registerBuiltinsMacroFuncs(out *macro.Map) {
|
|||
registerStringMacroFuncs(out.String)
|
||||
registerNumberMacroFuncs(out.Number)
|
||||
registerInt64MacroFuncs(out.Int64)
|
||||
registerUint8MacroFuncs(out.Uint8)
|
||||
registerUint64MacroFuncs(out.Uint64)
|
||||
registerAlphabeticalMacroFuncs(out.Alphabetical)
|
||||
registerFileMacroFuncs(out.File)
|
||||
|
@ -176,6 +177,51 @@ func registerInt64MacroFuncs(out *macro.Macro) {
|
|||
})
|
||||
}
|
||||
|
||||
// Uint8
|
||||
// 0 to 255.
|
||||
func registerUint8MacroFuncs(out *macro.Macro) {
|
||||
// checks if the param value's uint8 representation is
|
||||
// bigger or equal than 'min'
|
||||
out.RegisterFunc("min", func(min uint8) macro.EvaluatorFunc {
|
||||
return func(paramValue string) bool {
|
||||
n, err := strconv.ParseUint(paramValue, 10, 8)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return uint8(n) >= min
|
||||
}
|
||||
})
|
||||
|
||||
// checks if the param value's uint8 representation is
|
||||
// smaller or equal than 'max'
|
||||
out.RegisterFunc("max", func(max uint8) macro.EvaluatorFunc {
|
||||
return func(paramValue string) bool {
|
||||
n, err := strconv.ParseUint(paramValue, 10, 8)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return uint8(n) <= max
|
||||
}
|
||||
})
|
||||
|
||||
// checks if the param value's uint8 representation is
|
||||
// between min and max, including 'min' and 'max'
|
||||
out.RegisterFunc("range", func(min, max uint8) macro.EvaluatorFunc {
|
||||
return func(paramValue string) bool {
|
||||
n, err := strconv.ParseUint(paramValue, 10, 8)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if v := uint8(n); v < min || v > max {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Uint64
|
||||
// 0 to 18446744073709551615.
|
||||
func registerUint64MacroFuncs(out *macro.Macro) {
|
||||
|
|
|
@ -26,6 +26,10 @@ const (
|
|||
// Allows only -9223372036854775808 to 9223372036854775807.
|
||||
// Declaration: /mypath/{myparam:int64} or {myparam:long}
|
||||
ParamTypeInt64
|
||||
// ParamTypeUint8 a number type.
|
||||
// Allows only 0 to 255.
|
||||
// Declaration: /mypath/{myparam:uint8}
|
||||
ParamTypeUint8
|
||||
// ParamTypeUint64 a number type.
|
||||
// Allows only 0 to 18446744073709551615.
|
||||
// Declaration: /mypath/{myparam:uint64}
|
||||
|
@ -88,6 +92,8 @@ func (pt ParamType) Kind() reflect.Kind {
|
|||
return reflect.Int
|
||||
case ParamTypeInt64:
|
||||
return reflect.Int64
|
||||
case ParamTypeUint8:
|
||||
return reflect.Uint8
|
||||
case ParamTypeUint64:
|
||||
return reflect.Uint64
|
||||
case ParamTypeBoolean:
|
||||
|
@ -106,6 +112,8 @@ func ValidKind(k reflect.Kind) bool {
|
|||
fallthrough
|
||||
case reflect.Int64:
|
||||
fallthrough
|
||||
case reflect.Uint8:
|
||||
fallthrough
|
||||
case reflect.Uint64:
|
||||
fallthrough
|
||||
case reflect.Bool:
|
||||
|
@ -128,6 +136,7 @@ var paramTypes = map[string]ParamType{
|
|||
"int": ParamTypeNumber, // same as number.
|
||||
"long": ParamTypeInt64,
|
||||
"int64": ParamTypeInt64, // same as long.
|
||||
"uint8": ParamTypeUint8,
|
||||
"uint64": ParamTypeUint64,
|
||||
|
||||
"boolean": ParamTypeBoolean,
|
||||
|
@ -149,6 +158,7 @@ var paramTypes = map[string]ParamType{
|
|||
// "string"
|
||||
// "number" or "int"
|
||||
// "long" or "int64"
|
||||
// "uint8"
|
||||
// "uint64"
|
||||
// "boolean" or "bool"
|
||||
// "alphabetical"
|
||||
|
@ -179,6 +189,8 @@ func LookupParamTypeFromStd(goType string) ParamType {
|
|||
return ParamTypeNumber
|
||||
case "int64":
|
||||
return ParamTypeInt64
|
||||
case "uint8":
|
||||
return ParamTypeUint8
|
||||
case "uint64":
|
||||
return ParamTypeUint64
|
||||
case "bool":
|
||||
|
|
|
@ -271,6 +271,9 @@ type Map struct {
|
|||
// int64 as int64 type
|
||||
// -9223372036854775808 to 9223372036854775807.
|
||||
Int64 *Macro
|
||||
// uint8 as uint8 type
|
||||
// 0 to 255.
|
||||
Uint8 *Macro
|
||||
// uint64 as uint64 type
|
||||
// 0 to 18446744073709551615.
|
||||
Uint64 *Macro
|
||||
|
@ -313,6 +316,7 @@ func NewMap() *Map {
|
|||
// if err == strconv.ErrRange...
|
||||
return err == nil
|
||||
}), //("^-[1-9]|-?[1-9][0-9]{1,14}|-?1000000000000000|-?10000000000000000|-?100000000000000000|-?[1-9]000000000000000000|-?9[0-2]00000000000000000|-?92[0-2]0000000000000000|-?922[0-3]000000000000000|-?9223[0-3]00000000000000|-?92233[0-7]0000000000000|-?922337[0-2]000000000000|-?92233720[0-3]0000000000|-?922337203[0-6]000000000|-?9223372036[0-8]00000000|-?92233720368[0-5]0000000|-?922337203685[0-4]000000|-?9223372036854[0-7]00000|-?92233720368547[0-7]0000|-?922337203685477[0-5]000|-?922337203685477[56]000|[0-9]$")),
|
||||
Uint8: newMacro(MustNewEvaluatorFromRegexp("^([0-9]|[1-8][0-9]|9[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")),
|
||||
Uint64: newMacro(func(paramValue string) bool {
|
||||
if !simpleNumberEvalutator(paramValue) {
|
||||
return false
|
||||
|
@ -346,6 +350,8 @@ func (m *Map) Lookup(typ ast.ParamType) *Macro {
|
|||
return m.Number
|
||||
case ast.ParamTypeInt64:
|
||||
return m.Int64
|
||||
case ast.ParamTypeUint8:
|
||||
return m.Uint8
|
||||
case ast.ParamTypeUint64:
|
||||
return m.Uint64
|
||||
case ast.ParamTypeBoolean:
|
||||
|
|
|
@ -142,6 +142,37 @@ func TestInt64EvaluatorRaw(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUint8EvaluatorRaw(t *testing.T) {
|
||||
f := NewMap()
|
||||
|
||||
tests := []struct {
|
||||
pass bool
|
||||
input string
|
||||
}{
|
||||
{false, "astring"}, // 0
|
||||
{false, "astringwith_numb3rS_and_symbol$"}, // 1
|
||||
{false, "-9223372036854775808"}, // 2
|
||||
{false, "main.css"}, // 3
|
||||
{false, "/assets/main.css"}, // 4
|
||||
{false, "92233720368547758079223372036854775807"}, // 5
|
||||
{false, "9223372036854775808 9223372036854775808"}, // 6
|
||||
{false, "-1"}, // 7
|
||||
{false, "-0"}, // 8
|
||||
{false, "+1"}, // 9
|
||||
{false, "18446744073709551615"}, // 10
|
||||
{false, "9223372036854775807"}, // 11
|
||||
{false, "021"}, // 12 - no leading zeroes are allowed.
|
||||
{false, "300"}, // 13
|
||||
{true, "0"}, // 14
|
||||
{true, "255"}, // 15
|
||||
{true, "21"}, // 16
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
testEvaluatorRaw(t, f.Uint8, tt.input, tt.pass, i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUint64EvaluatorRaw(t *testing.T) {
|
||||
f := NewMap()
|
||||
|
||||
|
|
6
doc.go
6
doc.go
|
@ -723,6 +723,12 @@ Standard macro types for parameters:
|
|||
int64 type
|
||||
-9223372036854775808 to 9223372036854775807
|
||||
|
||||
+------------------------+
|
||||
| {param:uint8} |
|
||||
+------------------------+
|
||||
uint8 type
|
||||
0 to 255
|
||||
|
||||
+------------------------+
|
||||
| {param:uint64} |
|
||||
+------------------------+
|
||||
|
|
|
@ -44,6 +44,13 @@ func resolveParam(currentParamIndex int, typ reflect.Type) (reflect.Value, bool)
|
|||
entry, _ := ctx.Params().GetEntryAt(currentParamIndex)
|
||||
v, _ := entry.Int64Default(0)
|
||||
|
||||
return v
|
||||
}
|
||||
case reflect.Uint8:
|
||||
fn = func(ctx context.Context) uint8 {
|
||||
entry, _ := ctx.Params().GetEntryAt(currentParamIndex)
|
||||
v, _ := entry.Uint8Default(0)
|
||||
|
||||
return v
|
||||
}
|
||||
case reflect.Uint64:
|
||||
|
|
|
@ -366,7 +366,8 @@ func (c *testControllerRelPathFromFunc) EndRequest(ctx context.Context) {
|
|||
|
||||
func (c *testControllerRelPathFromFunc) Get() {}
|
||||
func (c *testControllerRelPathFromFunc) GetBy(uint64) {}
|
||||
func (c *testControllerRelPathFromFunc) GetRatioBy(int64) {}
|
||||
func (c *testControllerRelPathFromFunc) GetUint8RatioBy(uint8) {}
|
||||
func (c *testControllerRelPathFromFunc) GetUint64RatioBy(int64) {}
|
||||
func (c *testControllerRelPathFromFunc) GetAnythingByWildcard(string) {}
|
||||
|
||||
func (c *testControllerRelPathFromFunc) GetLogin() {}
|
||||
|
@ -391,8 +392,11 @@ func TestControllerRelPathFromFunc(t *testing.T) {
|
|||
|
||||
e.GET("/18446744073709551615").Expect().Status(iris.StatusOK).
|
||||
Body().Equal("GET:/18446744073709551615")
|
||||
e.GET("/ratio/-42").Expect().Status(iris.StatusOK).
|
||||
Body().Equal("GET:/ratio/-42")
|
||||
e.GET("/uint8/ratio/255").Expect().Status(iris.StatusOK).
|
||||
Body().Equal("GET:/uint8/ratio/255")
|
||||
e.GET("/uint8/ratio/256").Expect().Status(iris.StatusNotFound)
|
||||
e.GET("/uint64/ratio/-42").Expect().Status(iris.StatusOK).
|
||||
Body().Equal("GET:/uint64/ratio/-42")
|
||||
e.GET("/something/true").Expect().Status(iris.StatusOK).
|
||||
Body().Equal("GET:/something/true")
|
||||
e.GET("/something/false").Expect().Status(iris.StatusOK).
|
||||
|
|
|
@ -47,6 +47,11 @@ func makeFuncParamGetter(paramType ast.ParamType, paramName string) reflect.Valu
|
|||
v, _ := ctx.Params().GetInt64(paramName)
|
||||
return v
|
||||
}
|
||||
case ast.ParamTypeUint8:
|
||||
fn = func(ctx context.Context) uint8 {
|
||||
v, _ := ctx.Params().GetUint8(paramName)
|
||||
return v
|
||||
}
|
||||
case ast.ParamTypeUint64:
|
||||
fn = func(ctx context.Context) uint64 {
|
||||
v, _ := ctx.Params().GetUint64(paramName)
|
||||
|
|
Loading…
Reference in New Issue
Block a user