this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add ergonomic param parsing

+108
+58
atproto/client/params.go
··· 1 + package client 2 + 3 + import ( 4 + "encoding" 5 + "fmt" 6 + "net/url" 7 + "reflect" 8 + ) 9 + 10 + // Flexibly parses an input map to URL query params (strings) 11 + func 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: 18 + if v { 19 + out.Set(k, "true") 20 + } else { 21 + out.Set(k, "false") 22 + } 23 + case string: 24 + out.Set(k, v) 25 + case int, uint, int8, int16, int32, int64, uint8, uint16, uint32, uint64: 26 + out.Set(k, fmt.Sprintf("%d", v)) 27 + case encoding.TextMarshaler: 28 + out.Set(k, fmt.Sprintf("%s", v)) 29 + default: 30 + ref := reflect.ValueOf(v) 31 + if ref.Kind() == reflect.Slice { 32 + for i := 0; i < ref.Len(); i++ { 33 + switch elem := ref.Index(i).Interface().(type) { 34 + case nil: 35 + out.Add(k, "") 36 + case bool: 37 + if elem { 38 + out.Add(k, "true") 39 + } else { 40 + out.Add(k, "false") 41 + } 42 + case string: 43 + out.Add(k, elem) 44 + case int, uint, int8, int16, int32, int64, uint8, uint16, uint32, uint64: 45 + out.Add(k, fmt.Sprintf("%d", elem)) 46 + case encoding.TextMarshaler: 47 + out.Add(k, fmt.Sprintf("%s", elem)) 48 + default: 49 + return nil, fmt.Errorf("can't marshal query param type: %T", v) 50 + } 51 + } 52 + } else { 53 + return nil, fmt.Errorf("can't marshal query param type: %T", v) 54 + } 55 + } 56 + } 57 + return out, nil 58 + }
+50
atproto/client/params_test.go
··· 1 + package client 2 + 3 + import ( 4 + "net/url" 5 + "testing" 6 + 7 + "github.com/bluesky-social/indigo/atproto/syntax" 8 + 9 + "github.com/stretchr/testify/assert" 10 + "github.com/stretchr/testify/require" 11 + ) 12 + 13 + func TestParseParams(t *testing.T) { 14 + assert := assert.New(t) 15 + require := require.New(t) 16 + 17 + { 18 + input := map[string]any{ 19 + "int": int(-1), 20 + "uint32": uint32(32), 21 + "str": "hello", 22 + "bool": true, 23 + "did": syntax.DID("did:web:example.com"), 24 + "multiBool": []bool{true, false}, 25 + "multiDID": []syntax.DID{syntax.DID("did:web:example.com"), syntax.DID("did:web:other.com")}, 26 + } 27 + expect := url.Values(map[string][]string{ 28 + "int": []string{"-1"}, 29 + "uint32": []string{"32"}, 30 + "str": []string{"hello"}, 31 + "bool": []string{"true"}, 32 + "did": []string{"did:web:example.com"}, 33 + "multiBool": []string{"true", "false"}, 34 + "multiDID": []string{"did:web:example.com", "did:web:other.com"}, 35 + }) 36 + output, err := ParseParams(input) 37 + require.NoError(err) 38 + assert.Equal(expect, output) 39 + } 40 + 41 + { 42 + // unsupported type 43 + input := map[string]any{ 44 + "map": map[string]int{"a": 123}, 45 + } 46 + _, err := ParseParams(input) 47 + assert.Error(err) 48 + } 49 + 50 + }