1
0
mirror of https://github.com/gofiber/fiber.git synced 2025-02-06 22:51:58 +00:00
fiber/utils.go
Iliya 43dc60fb27
(v3) feature: Implement new generic functions: Params, Get and Convert (#2850)
* 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>
2024-03-18 15:02:15 +01:00

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
}