Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -504,6 +505,79 @@ func (c *Context) Param(key string) string {
return c.Params.ByName(key)
}

// ParamInt returns the URL param for the given key as an int.
func (c *Context) ParamInt(key string) (int, error) {
return strconv.Atoi(c.Param(key))
}

// ParamInt8 returns the URL param for the given key as an int8.
func (c *Context) ParamInt8(key string) (int8, error) {
value, err := strconv.ParseInt(c.Param(key), 10, 8)
return int8(value), err
}

// ParamInt16 returns the URL param for the given key as an int16.
func (c *Context) ParamInt16(key string) (int16, error) {
value, err := strconv.ParseInt(c.Param(key), 10, 16)
return int16(value), err
}

// ParamInt32 returns the URL param for the given key as an int32.
func (c *Context) ParamInt32(key string) (int32, error) {
value, err := strconv.ParseInt(c.Param(key), 10, 32)
return int32(value), err
}

// ParamInt64 returns the URL param for the given key as an int64.
func (c *Context) ParamInt64(key string) (int64, error) {
return strconv.ParseInt(c.Param(key), 10, 64)
}

// ParamUint returns the URL param for the given key as a uint.
func (c *Context) ParamUint(key string) (uint, error) {
value, err := strconv.ParseUint(c.Param(key), 10, 0)
return uint(value), err
}

// ParamUint8 returns the URL param for the given key as a uint8.
func (c *Context) ParamUint8(key string) (uint8, error) {
value, err := strconv.ParseUint(c.Param(key), 10, 8)
return uint8(value), err
}

// ParamUint16 returns the URL param for the given key as a uint16.
func (c *Context) ParamUint16(key string) (uint16, error) {
value, err := strconv.ParseUint(c.Param(key), 10, 16)
return uint16(value), err
}

// ParamUint32 returns the URL param for the given key as a uint32.
func (c *Context) ParamUint32(key string) (uint32, error) {
value, err := strconv.ParseUint(c.Param(key), 10, 32)
return uint32(value), err
}

// ParamUint64 returns the URL param for the given key as a uint64.
func (c *Context) ParamUint64(key string) (uint64, error) {
return strconv.ParseUint(c.Param(key), 10, 64)
}

// ParamFloat32 returns the URL param for the given key as a float32.
func (c *Context) ParamFloat32(key string) (float32, error) {
value, err := strconv.ParseFloat(c.Param(key), 32)
return float32(value), err
}

// ParamFloat64 returns the URL param for the given key as a float64.
func (c *Context) ParamFloat64(key string) (float64, error) {
return strconv.ParseFloat(c.Param(key), 64)
}

// ParamBool returns the URL param for the given key as a boolean.
func (c *Context) ParamBool(key string) (bool, error) {
return strconv.ParseBool(c.Param(key))
}

// AddParam adds param to context and
// replaces path param key with given value for e2e testing purposes
// Example Route: "/user/:id"
Expand Down
107 changes: 107 additions & 0 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3352,6 +3352,113 @@ func TestContextAddParam(t *testing.T) {
assert.Equal(t, value, v)
}

func TestContextParamTyped(t *testing.T) {
tests := []struct {
name string
value string
call func(*Context) (any, error)
want any
}{
{
name: "int",
value: "42",
call: func(c *Context) (any, error) { return c.ParamInt("value") },
want: 42,
},
{
name: "int8",
value: "127",
call: func(c *Context) (any, error) { return c.ParamInt8("value") },
want: int8(127),
},
{
name: "int16",
value: "32767",
call: func(c *Context) (any, error) { return c.ParamInt16("value") },
want: int16(32767),
},
{
name: "int32",
value: "2147483647",
call: func(c *Context) (any, error) { return c.ParamInt32("value") },
want: int32(2147483647),
},
{
name: "int64",
value: "9223372036854775807",
call: func(c *Context) (any, error) { return c.ParamInt64("value") },
want: int64(9223372036854775807),
},
{
name: "uint",
value: "42",
call: func(c *Context) (any, error) { return c.ParamUint("value") },
want: uint(42),
},
{
name: "uint8",
value: "255",
call: func(c *Context) (any, error) { return c.ParamUint8("value") },
want: uint8(255),
},
{
name: "uint16",
value: "65535",
call: func(c *Context) (any, error) { return c.ParamUint16("value") },
want: uint16(65535),
},
{
name: "uint32",
value: "4294967295",
call: func(c *Context) (any, error) { return c.ParamUint32("value") },
want: uint32(4294967295),
},
{
name: "uint64",
value: "18446744073709551615",
call: func(c *Context) (any, error) { return c.ParamUint64("value") },
want: uint64(18446744073709551615),
},
{
name: "float32",
value: "2.5",
call: func(c *Context) (any, error) { return c.ParamFloat32("value") },
want: float32(2.5),
},
{
name: "float64",
value: "2.5",
call: func(c *Context) (any, error) { return c.ParamFloat64("value") },
want: float64(2.5),
},
{
name: "bool",
value: "true",
call: func(c *Context) (any, error) { return c.ParamBool("value") },
want: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &Context{Params: Params{{Key: "value", Value: tt.value}}}
got, err := tt.call(c)
assert.NoError(t, err)
assert.Equal(t, tt.want, got)
})
}
}

func TestContextParamTypedErrors(t *testing.T) {
c := &Context{Params: Params{{Key: "value", Value: "nope"}}}
_, err := c.ParamInt("value")
assert.Error(t, err)

c = &Context{Params: Params{{Key: "value", Value: "-1"}}}
_, err = c.ParamUint("value")
assert.Error(t, err)
}

func TestCreateTestContextWithRouteParams(t *testing.T) {
w := httptest.NewRecorder()
engine := New()
Expand Down