+`)
+//line index.qtpl:12
+}
+
+//line index.qtpl:12
+func (i *Index) WriteBody(qq422016 qtio422016.Writer) {
+ //line index.qtpl:12
+ qw422016 := qt422016.AcquireWriter(qq422016)
+ //line index.qtpl:12
+ i.StreamBody(qw422016)
+ //line index.qtpl:12
+ qt422016.ReleaseWriter(qw422016)
+//line index.qtpl:12
+}
+
+//line index.qtpl:12
+func (i *Index) Body() string {
+ //line index.qtpl:12
+ qb422016 := qt422016.AcquireByteBuffer()
+ //line index.qtpl:12
+ i.WriteBody(qb422016)
+ //line index.qtpl:12
+ qs422016 := string(qb422016.B)
+ //line index.qtpl:12
+ qt422016.ReleaseByteBuffer(qb422016)
+ //line index.qtpl:12
+ return qs422016
+//line index.qtpl:12
+}
diff --git a/_examples/structuring/bootstrap/main.go b/_examples/structuring/bootstrap/main.go
index 158b31c4..3d335caf 100644
--- a/_examples/structuring/bootstrap/main.go
+++ b/_examples/structuring/bootstrap/main.go
@@ -6,9 +6,14 @@ import (
"github.com/kataras/iris/_examples/structuring/bootstrap/routes"
)
-func main() {
+func newApp() *bootstrap.Bootstrapper {
app := bootstrap.New("Awesome App", "kataras2006@hotmail.com")
app.Bootstrap()
app.Configure(identity.Configure, routes.Configure)
+ return app
+}
+
+func main() {
+ app := newApp()
app.Listen(":8080")
}
diff --git a/_examples/structuring/bootstrap/main_test.go b/_examples/structuring/bootstrap/main_test.go
index e9d5065e..1fe5f562 100644
--- a/_examples/structuring/bootstrap/main_test.go
+++ b/_examples/structuring/bootstrap/main_test.go
@@ -8,6 +8,7 @@ import (
// go test -v
func TestApp(t *testing.T) {
+ app := newApp()
e := httptest.New(t, app.Application)
// test our routes
diff --git a/_examples/websocket/connectionlist/main.go b/_examples/websocket/connectionlist/main.go
index f13bc02f..f736bb21 100644
--- a/_examples/websocket/connectionlist/main.go
+++ b/_examples/websocket/connectionlist/main.go
@@ -77,7 +77,7 @@ func main() {
go func() {
i := 0
- for range time.Tick(1*time.Second){ //another way to get clock signal
+ for range time.Tick(1 * time.Second) { //another way to get clock signal
mutex.Lock()
broadcast(Conn, fmt.Sprintf("aaaa2 %d\n", i))
mutex.Unlock()
diff --git a/context/context.go b/context/context.go
index ee09f300..b357f936 100644
--- a/context/context.go
+++ b/context/context.go
@@ -91,6 +91,17 @@ func (r *RequestParams) Visit(visitor func(key string, value string)) {
})
}
+// GetEntry returns the internal Entry of the memstore, as value
+// if not found then it returns a zero Entry and false.
+func (r RequestParams) GetEntry(key string) (memstore.Entry, bool) {
+ // we don't return the pointer here, we don't want to give the end-developer
+ // the strength to change the entry that way.
+ if e := r.store.GetEntry(key); e != nil {
+ return *e, true
+ }
+ return memstore.Entry{}, false
+}
+
// Get returns a path parameter's value based on its route's dynamic path key.
func (r RequestParams) Get(key string) string {
return r.store.GetString(key)
diff --git a/core/memstore/memstore.go b/core/memstore/memstore.go
index ed6bd78b..93e5a557 100644
--- a/core/memstore/memstore.go
+++ b/core/memstore/memstore.go
@@ -25,6 +25,150 @@ type (
Store []Entry
)
+func (e Entry) GetByKindOrNil(k reflect.Kind) interface{} {
+ switch k {
+ case reflect.String:
+ v := e.StringDefault("__$nf")
+ if v == "__$nf" {
+ return nil
+ }
+ return v
+ case reflect.Int:
+ v, err := e.IntDefault(-1)
+ if err != nil || v == -1 {
+ return nil
+ }
+ return v
+ case reflect.Int64:
+ v, err := e.Int64Default(-1)
+ if err != nil || v == -1 {
+ return nil
+ }
+ return v
+ case reflect.Bool:
+ v, err := e.BoolDefault(false)
+ if err != nil {
+ return nil
+ }
+ return v
+ default:
+ return e.ValueRaw
+ }
+}
+
+// StringDefault returns the entry's value as string.
+// If not found returns "def".
+func (e Entry) StringDefault(def string) string {
+ v := e.ValueRaw
+
+ if vString, ok := v.(string); ok {
+ return vString
+ }
+
+ return def
+}
+
+// String returns the entry's value as string.
+func (e Entry) String() string {
+ return e.StringDefault("")
+}
+
+// StringTrim returns the entry's string value without trailing spaces.
+func (e Entry) StringTrim() string {
+ return strings.TrimSpace(e.String())
+}
+
+// ErrIntParse returns an error message when int parse failed
+// it's not statical error, it depends on the failed value.
+var ErrIntParse = errors.New("unable to find or parse the integer, found: %#v")
+
+// IntDefault returns the entry's value as int.
+// If not found returns "def".
+func (e Entry) IntDefault(def int) (int, error) {
+ v := e.ValueRaw
+ if v == nil {
+ return def, nil
+ }
+ if vint, ok := v.(int); ok {
+ return vint, nil
+ } else if vstring, sok := v.(string); sok {
+ if vstring == "" {
+ return def, nil
+ }
+ return strconv.Atoi(vstring)
+ }
+
+ return def, nil
+}
+
+// Int64Default returns the entry's value as int64.
+// If not found returns "def".
+func (e Entry) Int64Default(def int64) (int64, error) {
+ v := e.ValueRaw
+ if v == nil {
+ return def, nil
+ }
+ if vint64, ok := v.(int64); ok {
+ return vint64, nil
+ } else if vstring, sok := v.(string); sok {
+ if vstring == "" {
+ return def, nil
+ }
+ return strconv.ParseInt(vstring, 10, 64)
+ }
+
+ return def, nil
+}
+
+// Float64Default returns the entry's value as float64.
+// If not found returns "def".
+func (e Entry) Float64Default(def float64) (float64, error) {
+ v := e.ValueRaw
+ if v == nil {
+ return def, nil
+ }
+ if vfloat64, ok := v.(float64); ok {
+ return vfloat64, nil
+ } else if vstring, sok := v.(string); sok {
+ if vstring == "" {
+ return def, nil
+ }
+ return strconv.ParseFloat(vstring, 64)
+ }
+
+ return def, nil
+}
+
+// BoolDefault returns the user's value as bool.
+// 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".
+// Any other value returns an error.
+//
+// If not found returns "def".
+func (e Entry) BoolDefault(def bool) (bool, error) {
+ v := e.ValueRaw
+ if v == nil {
+ return def, nil
+ }
+
+ if vBoolean, ok := v.(bool); ok {
+ return vBoolean, nil
+ }
+
+ if vString, ok := v.(string); ok {
+ return strconv.ParseBool(vString)
+ }
+
+ if vInt, ok := v.(int); ok {
+ if vInt == 1 {
+ return true, nil
+ }
+ return false, nil
+ }
+
+ return def, nil
+}
+
// Value returns the value of the entry,
// respects the immutable.
func (e Entry) Value() interface{} {
@@ -128,19 +272,35 @@ func (r *Store) SetImmutable(key string, value interface{}) (Entry, bool) {
return r.Save(key, value, true)
}
-// GetDefault returns the entry's value based on its key.
-// If not found returns "def".
-func (r *Store) GetDefault(key string, def interface{}) interface{} {
+// GetEntry returns a pointer to the "Entry" found with the given "key"
+// if nothing found then it returns nil, so be careful with that,
+// it's not supposed to be used by end-developers.
+func (r *Store) GetEntry(key string) *Entry {
args := *r
n := len(args)
for i := 0; i < n; i++ {
kv := &args[i]
if kv.Key == key {
- return kv.Value()
+ return kv
}
}
- return def
+ return nil
+}
+
+// GetDefault returns the entry's value based on its key.
+// If not found returns "def".
+// This function checks for immutability as well, the rest don't.
+func (r *Store) GetDefault(key string, def interface{}) interface{} {
+ v := r.GetEntry(key)
+ if v == nil || v.ValueRaw == nil {
+ return def
+ }
+ vv := v.Value()
+ if vv == nil {
+ return def
+ }
+ return vv
}
// Get returns the entry's value based on its key.
@@ -162,16 +322,12 @@ func (r *Store) Visit(visitor func(key string, value interface{})) {
// GetStringDefault returns the entry's value as string, based on its key.
// If not found returns "def".
func (r *Store) GetStringDefault(key string, def string) string {
- v := r.Get(key)
+ v := r.GetEntry(key)
if v == nil {
return def
}
- if vString, ok := v.(string); ok {
- return vString
- }
-
- return def
+ return v.StringDefault(def)
}
// GetString returns the entry's value as string, based on its key.
@@ -184,27 +340,14 @@ func (r *Store) GetStringTrim(name string) string {
return strings.TrimSpace(r.GetString(name))
}
-// ErrIntParse returns an error message when int parse failed
-// it's not statical error, it depends on the failed value.
-var ErrIntParse = errors.New("unable to find or parse the integer, found: %#v")
-
// GetIntDefault returns the entry's value as int, based on its key.
// If not found returns "def".
func (r *Store) GetIntDefault(key string, def int) (int, error) {
- v := r.Get(key)
+ v := r.GetEntry(key)
if v == nil {
return def, nil
}
- if vint, ok := v.(int); ok {
- return vint, nil
- } else if vstring, sok := v.(string); sok {
- if vstring == "" {
- return def, nil
- }
- return strconv.Atoi(vstring)
- }
-
- return def, nil
+ return v.IntDefault(def)
}
// GetInt returns the entry's value as int, based on its key.
@@ -216,20 +359,11 @@ func (r *Store) GetInt(key string) (int, error) {
// GetInt64Default returns the entry's value as int64, based on its key.
// If not found returns "def".
func (r *Store) GetInt64Default(key string, def int64) (int64, error) {
- v := r.Get(key)
+ v := r.GetEntry(key)
if v == nil {
return def, nil
}
- if vint64, ok := v.(int64); ok {
- return vint64, nil
- } else if vstring, sok := v.(string); sok {
- if vstring == "" {
- return def, nil
- }
- return strconv.ParseInt(vstring, 10, 64)
- }
-
- return def, nil
+ return v.Int64Default(def)
}
// GetInt64 returns the entry's value as int64, based on its key.
@@ -241,20 +375,11 @@ func (r *Store) GetInt64(key string) (int64, error) {
// GetFloat64Default returns the entry's value as float64, based on its key.
// If not found returns "def".
func (r *Store) GetFloat64Default(key string, def float64) (float64, error) {
- v := r.Get(key)
+ v := r.GetEntry(key)
if v == nil {
return def, nil
}
- if vfloat64, ok := v.(float64); ok {
- return vfloat64, nil
- } else if vstring, sok := v.(string); sok {
- if vstring == "" {
- return def, nil
- }
- return strconv.ParseFloat(vstring, 64)
- }
-
- return def, nil
+ return v.Float64Default(def)
}
// GetFloat64 returns the entry's value as float64, based on its key.
@@ -270,27 +395,11 @@ func (r *Store) GetFloat64(key string) (float64, error) {
//
// If not found returns "def".
func (r *Store) GetBoolDefault(key string, def bool) (bool, error) {
- v := r.Get(key)
+ v := r.GetEntry(key)
if v == nil {
return def, nil
}
-
- if vBoolean, ok := v.(bool); ok {
- return vBoolean, nil
- }
-
- if vString, ok := v.(string); ok {
- return strconv.ParseBool(vString)
- }
-
- if vInt, ok := v.(int); ok {
- if vInt == 1 {
- return true, nil
- }
- return false, nil
- }
-
- return def, nil
+ return v.BoolDefault(def)
}
// GetBool returns the user's value as bool, based on its key.
diff --git a/core/router/macro/interpreter/ast/ast.go b/core/router/macro/interpreter/ast/ast.go
index 0f5b33d7..1e39bc85 100644
--- a/core/router/macro/interpreter/ast/ast.go
+++ b/core/router/macro/interpreter/ast/ast.go
@@ -51,6 +51,23 @@ const (
ParamTypePath
)
+// ValidKind will return true if at least one param type is supported
+// for this std kind.
+func ValidKind(k reflect.Kind) bool {
+ switch k {
+ case reflect.String:
+ fallthrough
+ case reflect.Int:
+ fallthrough
+ case reflect.Int64:
+ fallthrough
+ case reflect.Bool:
+ return true
+ default:
+ return false
+ }
+}
+
// Not because for a single reason
// a string may be a
// ParamTypeString or a ParamTypeFile
@@ -105,6 +122,7 @@ var paramTypes = map[string]ParamType{
// Available:
// "string"
// "int"
+// "long"
// "alphabetical"
// "file"
// "path"