Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion httputilx/httputilx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func TestFetch(t *testing.T) {
cases := []struct {
in, want, wantErr string
}{
{"http://example.com", "<html>", ""},
{"http://example.com", "<html", ""},
{"http://fairly-certain-this-doesnt-exist-asdasd12g1ghdfddd.com", "", "cannot download"},
{"http://httpbin.org/status/400", "", "400"},
{"http://httpbin.org/status/500", "", "500"},
Expand Down
19 changes: 14 additions & 5 deletions sliceutil/sliceutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,27 @@ func FilterEmpty[T comparable](t T) bool {
}

// Map returns a list where each item in list has been modified by fn
func Map[T comparable](tt []T, fn func(T) T) []T {
ret := make([]T, len(tt))
func Map[InputTyp, OutputTyp any](tt []InputTyp, fn func(InputTyp) OutputTyp) []OutputTyp {
ret := make([]OutputTyp, len(tt))
for i, t := range tt {
ret[i] = fn(t)
}

return ret
}

// InterfaceSliceTo converts []interface to any given slice.
// It will ~optimistically~ try to convert interface item to the dst item type
func InterfaceSliceTo(src []interface{}, dst interface{}) interface{} {
// Reduce returns an aggregation of tt
func Reduce[InputTyp, AccTyp any](tt []InputTyp, fn func(AccTyp, InputTyp) AccTyp, acc AccTyp) AccTyp {
for _, t := range tt {
acc = fn(acc, t)
}

return acc
}

// InterfaceSliceTo converts []any to any given slice.
// It will ~optimistically~ try to convert any item to the dst item type
func InterfaceSliceTo(src []any, dst any) any {
dstt := reflect.TypeOf(dst)
if dstt.Kind() != reflect.Slice {
panic("`dst` is not an slice")
Expand Down
66 changes: 66 additions & 0 deletions sliceutil/sliceutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,72 @@ func TestMap_String(t *testing.T) {
}
}

func TestMap_Int(t *testing.T) {
cases := []struct {
in []string
want []int
f func(string) int
}{
{
in: []string{"1", "5", "2"},
want: []int{1, 5, 2},
f: func(s string) int {
n, _ := strconv.Atoi(s) // notlint: errcheck
return n
},
},
}
for _, tc := range cases {
t.Run("", func(t *testing.T) {
out := Map(tc.in, tc.f)
if !reflect.DeepEqual(tc.want, out) {
t.Errorf("\nout: %#v\nwant: %#v\n", out, tc.want)
}
})
}
}

func TestReduce_Int(t *testing.T) {
cases := []struct {
in []int
want int64
f func(int64, int) int64
}{
{
in: []int{1, 5, 2},
want: 8,
f: func(acc int64, i int) int64 {
return acc + int64(i)
},
},
}
for _, tc := range cases {
t.Run("", func(t *testing.T) {
out := Reduce(tc.in, tc.f, 0)
if !reflect.DeepEqual(tc.want, out) {
t.Errorf("\nout: %#v\nwant: %#v\n", out, tc.want)
}
})
}
}

func TestReduce_Struct(t *testing.T) {
type Acc struct {
acc int
}

out := Reduce(
[]int{1, 2, 3},
func(out Acc, i int) Acc {
out.acc += i
return out
},
Acc{})
if out.acc != 6 {
t.Errorf("\nout: %#v\nwant: %#v\n", out.acc, 6)
}
}

func TestInterfaceSliceTo(t *testing.T) {
{
src := []interface{}{"1", "2", "3", "4", "5"}
Expand Down