mirror of
https://github.com/gofiber/fiber.git
synced 2025-02-06 22:51:58 +00:00
* feature: implement generic params function * update: add ctx generic params benchmark function * fix: fix linter errors on boolean types * fix: fix linter errors on float variable types * tests: add Test_Params_TypeAssertFail Co-authored-by: Jason McNeil <sixcolors@mac.com> * Update ctx_test.go * typo: change genericType typo to GenericType in documents * remove ParamsInt method and rewrite Params method * add genericParseType tests and benchmarks and simplify genericQuery and genericParams tests and benchmarks * added GetReqHeader generic function * added tests for params generic function * add tests for GetReqHeader generic function * added GetReqHeader generic function * Revert "added GetReqHeader generic function" This reverts commit a63cebb7121fdd315c53b6f0aa3042612a0d23ac. * fix tests and benchamarks of generic tests * added default value to array test genericParse * fix Params generic function on default value and fixes some tests and typos * remove Test_Params_TypeAssertFail function(it didn't panic anyway) * fix bad usage on parallel tests * add convert function * fix generic tests * fix fail tests on use parallel multiple time * fix typo on params comment section * remove pointer refer on Convert * update generic benchmarks * reslove conflicts1 * add specific tests to integer and unsigned integer generic parser * fix typo on Convert document * change uint tests of Test_genericParseTypeInts * move generic types to utils.go file and change bitsize of int value type to 0 * update genericParseInt unit tests * update generic uint tests and pass value type in check functions * reverse dependency of Params and genericParams * update convert docs --------- Co-authored-by: Jason McNeil <sixcolors@mac.com> Co-authored-by: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Co-authored-by: RW <rene@gofiber.io>
113 lines
3.9 KiB
Go
113 lines
3.9 KiB
Go
package fiber
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
// assertValueType asserts the type of the result to the type of the value
|
|
func assertValueType[V GenericType, T any](result T) V {
|
|
v, ok := any(result).(V)
|
|
if !ok {
|
|
panic(fmt.Errorf("failed to type-assert to %T", v))
|
|
}
|
|
return v
|
|
}
|
|
|
|
func genericParseDefault[V GenericType](err error, parser func() V, defaultValue ...V) V {
|
|
var v V
|
|
if err != nil {
|
|
if len(defaultValue) > 0 {
|
|
return defaultValue[0]
|
|
}
|
|
return v
|
|
}
|
|
return parser()
|
|
}
|
|
|
|
func genericParseInt[V GenericType](str string, bitSize int, parser func(int64) V, defaultValue ...V) V {
|
|
result, err := strconv.ParseInt(str, 10, bitSize)
|
|
return genericParseDefault[V](err, func() V { return parser(result) }, defaultValue...)
|
|
}
|
|
|
|
func genericParseUint[V GenericType](str string, bitSize int, parser func(uint64) V, defaultValue ...V) V {
|
|
result, err := strconv.ParseUint(str, 10, bitSize)
|
|
return genericParseDefault[V](err, func() V { return parser(result) }, defaultValue...)
|
|
}
|
|
|
|
func genericParseFloat[V GenericType](str string, bitSize int, parser func(float64) V, defaultValue ...V) V {
|
|
result, err := strconv.ParseFloat(str, bitSize)
|
|
return genericParseDefault[V](err, func() V { return parser(result) }, defaultValue...)
|
|
}
|
|
|
|
func genericParseBool[V GenericType](str string, parser func(bool) V, defaultValue ...V) V {
|
|
result, err := strconv.ParseBool(str)
|
|
return genericParseDefault[V](err, func() V { return parser(result) }, defaultValue...)
|
|
}
|
|
|
|
func genericParseType[V GenericType](str string, v V, defaultValue ...V) V {
|
|
switch any(v).(type) {
|
|
case int:
|
|
return genericParseInt[V](str, 0, func(i int64) V { return assertValueType[V, int](int(i)) }, defaultValue...)
|
|
case int8:
|
|
return genericParseInt[V](str, 8, func(i int64) V { return assertValueType[V, int8](int8(i)) }, defaultValue...)
|
|
case int16:
|
|
return genericParseInt[V](str, 16, func(i int64) V { return assertValueType[V, int16](int16(i)) }, defaultValue...)
|
|
case int32:
|
|
return genericParseInt[V](str, 32, func(i int64) V { return assertValueType[V, int32](int32(i)) }, defaultValue...)
|
|
case int64:
|
|
return genericParseInt[V](str, 64, func(i int64) V { return assertValueType[V, int64](i) }, defaultValue...)
|
|
case uint:
|
|
return genericParseUint[V](str, 32, func(i uint64) V { return assertValueType[V, uint](uint(i)) }, defaultValue...)
|
|
case uint8:
|
|
return genericParseUint[V](str, 8, func(i uint64) V { return assertValueType[V, uint8](uint8(i)) }, defaultValue...)
|
|
case uint16:
|
|
return genericParseUint[V](str, 16, func(i uint64) V { return assertValueType[V, uint16](uint16(i)) }, defaultValue...)
|
|
case uint32:
|
|
return genericParseUint[V](str, 32, func(i uint64) V { return assertValueType[V, uint32](uint32(i)) }, defaultValue...)
|
|
case uint64:
|
|
return genericParseUint[V](str, 64, func(i uint64) V { return assertValueType[V, uint64](i) }, defaultValue...)
|
|
case float32:
|
|
return genericParseFloat[V](str, 32, func(i float64) V { return assertValueType[V, float32](float32(i)) }, defaultValue...)
|
|
case float64:
|
|
return genericParseFloat[V](str, 64, func(i float64) V { return assertValueType[V, float64](i) }, defaultValue...)
|
|
case bool:
|
|
return genericParseBool[V](str, func(b bool) V { return assertValueType[V, bool](b) }, defaultValue...)
|
|
case string:
|
|
if str == "" && len(defaultValue) > 0 {
|
|
return defaultValue[0]
|
|
}
|
|
return assertValueType[V, string](str)
|
|
case []byte:
|
|
if str == "" && len(defaultValue) > 0 {
|
|
return defaultValue[0]
|
|
}
|
|
return assertValueType[V, []byte]([]byte(str))
|
|
default:
|
|
if len(defaultValue) > 0 {
|
|
return defaultValue[0]
|
|
}
|
|
return v
|
|
}
|
|
}
|
|
|
|
type GenericType interface {
|
|
GenericTypeInteger | GenericTypeFloat | bool | string | []byte
|
|
}
|
|
|
|
type GenericTypeInteger interface {
|
|
GenericTypeIntegerSigned | GenericTypeIntegerUnsigned
|
|
}
|
|
|
|
type GenericTypeIntegerSigned interface {
|
|
int | int8 | int16 | int32 | int64
|
|
}
|
|
|
|
type GenericTypeIntegerUnsigned interface {
|
|
uint | uint8 | uint16 | uint32 | uint64
|
|
}
|
|
|
|
type GenericTypeFloat interface {
|
|
float32 | float64
|
|
}
|