1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-21 11:57:02 +00:00

Conversion once at macros and their functions, internal changes required

Former-commit-id: 7b778cccfb7c0e30ca5e8106017ada065993aba5
This commit is contained in:
Gerasimos (Makis) Maropoulos
2018-09-27 03:17:45 +03:00
parent dc3c38b189
commit d6d27b2605
11 changed files with 338 additions and 279 deletions

View File

@@ -2,7 +2,6 @@ package main
import (
"regexp"
"strconv"
"github.com/kataras/iris"
)
@@ -122,17 +121,12 @@ func main() {
// Let's register our first macro attached to uint64 macro type.
// "min" = the function
// "minValue" = the argument of the function
// func(string) bool = the macro's path parameter evaluator, this executes in serve time when
// func(uint64) bool = our func's evaluator, this executes in serve time when
// a user requests a path which contains the :uint64 macro parameter type with the min(...) macro parameter function.
app.Macros().Uint64.RegisterFunc("min", func(minValue uint64) func(string) bool {
// do anything before serve here [...]
// at this case we don't need to do anything
return func(paramValue string) bool {
n, err := strconv.ParseUint(paramValue, 10, 64)
if err != nil {
return false
}
return n >= minValue
app.Macros().Get("uint64").RegisterFunc("min", func(minValue uint64) func(uint64) bool {
// type of "paramValue" should match the type of the internal macro's evaluator function, which in this case is "uint64".
return func(paramValue uint64) bool {
return paramValue >= minValue
}
})
@@ -142,14 +136,14 @@ func main() {
app.Get("/profile/{id:uint64 min(20)}", func(ctx iris.Context) {
// second parameter is the error but it will always nil because we use macros,
// the validaton already happened.
id, _ := ctx.Params().GetInt("id")
id := ctx.Params().GetUint64Default("id", 0)
ctx.Writef("Hello id: %d", id)
})
// to change the error code per route's macro evaluator:
app.Get("/profile/{id:uint64 min(1)}/friends/{friendid:uint64 min(1) else 504}", func(ctx iris.Context) {
id, _ := ctx.Params().GetInt("id") // or GetUint64.
friendid, _ := ctx.Params().GetInt("friendid")
id := ctx.Params().GetUint64Default("id", 0)
friendid := ctx.Params().GetUint64Default("friendid", 0)
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.
@@ -169,7 +163,7 @@ func main() {
}
// MatchString is a type of func(string) bool, so we use it as it is.
app.Macros().String.RegisterFunc("coordinate", latLonRegex.MatchString)
app.Macros().Get("string").RegisterFunc("coordinate", latLonRegex.MatchString)
app.Get("/coordinates/{lat:string coordinate() else 502}/{lon:string coordinate() else 502}", func(ctx iris.Context) {
ctx.Writef("Lat: %s | Lon: %s", ctx.Params().Get("lat"), ctx.Params().Get("lon"))
@@ -178,7 +172,7 @@ func main() {
//
// Another one is by using a custom body.
app.Macros().String.RegisterFunc("range", func(minLength, maxLength int) func(string) bool {
app.Macros().Get("string").RegisterFunc("range", func(minLength, maxLength int) func(string) bool {
return func(paramValue string) bool {
return len(paramValue) >= minLength && len(paramValue) <= maxLength
}
@@ -193,7 +187,7 @@ func main() {
//
// Register your custom macro function which accepts a slice of strings `[...,...]`.
app.Macros().String.RegisterFunc("has", func(validNames []string) func(string) bool {
app.Macros().Get("string").RegisterFunc("has", func(validNames []string) func(string) bool {
return func(paramValue string) bool {
for _, validName := range validNames {
if validName == paramValue {

View File

@@ -16,37 +16,49 @@ func main() {
app.Logger().SetLevel("debug")
// Let's see how we can register a custom macro such as ":uint32" or ":small" for its alias (optionally) for Uint32 types.
app.Macros().Register("uint32", "small", false, false, func(paramValue string) bool {
_, err := strconv.ParseUint(paramValue, 10, 32)
return err == nil
}).
RegisterFunc("min", func(min uint32) func(string) bool {
return func(paramValue string) bool {
n, err := strconv.ParseUint(paramValue, 10, 32)
if err != nil {
return false
}
// app.Macros().Register("uint32", "small", false, false, func(paramValue string) bool {
// _, err := strconv.ParseUint(paramValue, 10, 32)
// return err == nil
// }).
// RegisterFunc("min", func(min uint32) func(string) bool {
// return func(paramValue string) bool {
// n, err := strconv.ParseUint(paramValue, 10, 32)
// if err != nil {
// return false
// }
return uint32(n) >= min
// return uint32(n) >= min
// }
// })
/* TODO:
somehow define one-time how the parameter should be parsed to a particular type (go std or custom)
tip: we can change the original value from string to X using the entry's.ValueRaw
^ Done 27 sep 2018.
*/
app.Macros().Register("uint32", "small", false, false, func(paramValue string) (interface{}, bool) {
v, err := strconv.ParseUint(paramValue, 10, 32)
return uint32(v), err == nil
}).
RegisterFunc("min", func(min uint32) func(uint32) bool {
return func(paramValue uint32) bool {
return paramValue >= min
}
})
/* TODO:
somehow define one-time how the parameter should be parsed to a particular type (go std or custom)
tip: we can change the original value from string to X using the entry's.ValueRaw
*/
// optionally, only when mvc or hero features are used for this custom macro/parameter type.
context.ParamResolvers[reflect.Uint32] = func(paramIndex int) interface{} {
// return func(store memstore.Store) uint32 {
// param, _ := store.GetEntryAt(paramIndex)
/* both works but second is faster, we omit the duplication of the type conversion over and over as of 27 Sep of 2018 (this patch)*/
// return func(ctx context.Context) uint32 {
// param := ctx.Params().GetEntryAt(paramIndex)
// paramValueAsUint32, _ := strconv.ParseUint(param.String(), 10, 32)
// return uint32(paramValueAsUint32)
// }
return func(ctx context.Context) uint32 {
param := ctx.Params().GetEntryAt(paramIndex)
paramValueAsUint32, _ := strconv.ParseUint(param.String(), 10, 32)
return uint32(paramValueAsUint32)
}
return ctx.Params().GetEntryAt(paramIndex).ValueRaw.(uint32)
} /* TODO: find a way to automative it based on the macro's first return value type, if thats the case then we must not return nil even if not found,
we must return a value i.e 0 for int for its interface{} */
}
//
@@ -54,11 +66,11 @@ func main() {
return fmt.Sprintf("Value of the parameter is: %d\n", paramValue)
}))
app.Get("test_uint64/{myparam:uint64}", handler)
app.Get("test_uint64/{myparam:uint64 min(5)}", func(ctx context.Context) {
// works: ctx.Writef("Value of the parameter is: %s\n", ctx.Params().Get("myparam"))
// but better and faster because the macro converts the string to uint64 automatically:
ctx.Writef("Value of the parameter is: %d\n", ctx.Params().GetUint64Default("myparam", 0))
})
app.Run(iris.Addr(":8080"))
}
func handler(ctx context.Context) {
ctx.Writef("Value of the parameter is: %s\n", ctx.Params().Get("myparam"))
}