Files
scrap/api/httpio/urlquery.go
2025-10-04 23:14:41 +02:00

87 lines
1.6 KiB
Go

package httpio
import (
"encoding/json"
"errors"
"net/http"
"strconv"
)
type URLQueryValueType interface {
string | int | float32 | float64 | bool
}
type iURLQueryKeyType interface {
GetKey() string
}
type URLQueryKeyType[T URLQueryValueType] struct {
Key string
_ T
}
func (u URLQueryKeyType[T]) GetKey() string { return u.Key }
func URLQueryKey[T URLQueryValueType](key string) iURLQueryKeyType {
return URLQueryKeyType[T]{
Key: key,
}
}
func ParseURLQuery[T IRequestIO](r *http.Request, keys ...iURLQueryKeyType) (*T, error) {
query := make(map[string]any, len(keys))
for _, key := range keys {
queryValue := r.URL.Query().Get(key.GetKey())
if queryValue == "" {
continue
}
switch key.(type) {
case URLQueryKeyType[string]:
query[key.GetKey()] = queryValue
case URLQueryKeyType[int]:
x, err := strconv.Atoi(queryValue)
if err != nil {
return nil, err
}
query[key.GetKey()] = x
case URLQueryKeyType[float32]:
x, err := strconv.ParseFloat(queryValue, 32)
if err != nil {
return nil, err
}
query[key.GetKey()] = x
case URLQueryKeyType[float64]:
x, err := strconv.ParseFloat(queryValue, 64)
if err != nil {
return nil, err
}
query[key.GetKey()] = x
case URLQueryKeyType[bool]:
x, err := strconv.ParseBool(queryValue)
if err != nil {
return nil, err
}
query[key.GetKey()] = x
default:
return nil, errors.New("unsupported URL query key type")
}
}
queryBytes, _ := json.Marshal(query)
var req T
err := json.Unmarshal(queryBytes, &req)
if err != nil {
return nil, err
}
return &req, nil
}