1package client
2
3import (
4 "encoding"
5 "fmt"
6 "net/url"
7 "reflect"
8)
9
10// Flexibly parses an input map to URL query params (strings)
11func ParseParams(raw map[string]any) (url.Values, error) {
12 out := make(url.Values)
13 for k := range raw {
14 switch v := raw[k].(type) {
15 case nil:
16 out.Set(k, "")
17 case bool, string, int, uint, int8, int16, int32, int64, uint8, uint16, uint32, uint64, uintptr:
18 out.Set(k, fmt.Sprint(v))
19 case encoding.TextMarshaler:
20 out.Set(k, fmt.Sprint(v))
21 default:
22 ref := reflect.ValueOf(v)
23 if ref.Kind() == reflect.Slice {
24 for i := 0; i < ref.Len(); i++ {
25 switch elem := ref.Index(i).Interface().(type) {
26 case nil:
27 out.Add(k, "")
28 case bool, string, int, uint, int8, int16, int32, int64, uint8, uint16, uint32, uint64, uintptr:
29 out.Add(k, fmt.Sprint(elem))
30 case encoding.TextMarshaler:
31 out.Add(k, fmt.Sprint(elem))
32 default:
33 return nil, fmt.Errorf("can't marshal query param '%s' with type: %T", k, v)
34 }
35 }
36 } else {
37 return nil, fmt.Errorf("can't marshal query param '%s' with type: %T", k, v)
38 }
39 }
40 }
41 return out, nil
42}