From dde45662bc7261df6547a5f0a921d392e055a8e7 Mon Sep 17 00:00:00 2001 From: Sugat Poudel Date: Wed, 5 Jun 2024 09:05:52 -0400 Subject: [PATCH] some more helpers --- codec_test.go | 4 ++++ numbers.go | 12 ++++++++++++ numbers_test.go | 12 ++++++++++++ slices.go | 10 ++++++++++ slices_test.go | 13 +++++++++++++ time.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ time_test.go | 18 ++++++++++++++++++ 7 files changed, 115 insertions(+) create mode 100644 numbers.go create mode 100644 numbers_test.go create mode 100644 time.go create mode 100644 time_test.go diff --git a/codec_test.go b/codec_test.go index ab3d34a..25c991e 100644 --- a/codec_test.go +++ b/codec_test.go @@ -51,4 +51,8 @@ func TestUnmarshalFromString(t *testing.T) { require.NoError(t, err) require.NotNil(t, decodedSlice) require.Equal(t, []string{"foo", "bar"}, *decodedSlice) + + decodedSlice, err = UnmarshalFromString[[]string]("null") + require.NoError(t, err) + require.Nil(t, decodedSlice) } diff --git a/numbers.go b/numbers.go new file mode 100644 index 0000000..75c3205 --- /dev/null +++ b/numbers.go @@ -0,0 +1,12 @@ +package mango + +// Min determines the minimum among the provided values +func Min(vals ...int) int { + min := vals[0] + for _, val := range vals { + if val < min { + min = val + } + } + return min +} diff --git a/numbers_test.go b/numbers_test.go new file mode 100644 index 0000000..40e75c0 --- /dev/null +++ b/numbers_test.go @@ -0,0 +1,12 @@ +package mango + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFindingMin(t *testing.T) { + min := Min(1, 2, 3, -594849) + assert.Equal(t, -594849, min) +} diff --git a/slices.go b/slices.go index c288c2d..3a1c464 100644 --- a/slices.go +++ b/slices.go @@ -17,3 +17,13 @@ func Filter[F any](list []F, predicate func(F) bool) []F { } return filtered } + +func Find[F any](list []F, predicate func(F) bool) (F, bool) { + var empty F + for _, item := range list { + if predicate(item) { + return item, true + } + } + return empty, false +} diff --git a/slices_test.go b/slices_test.go index 8fe70e1..864e8d3 100644 --- a/slices_test.go +++ b/slices_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestMap(t *testing.T) { @@ -23,3 +24,15 @@ func TestFilter(t *testing.T) { assert.Equal(t, expected, actual) } + +func TestFind(t *testing.T) { + lst := []int{1, 2, 3} + + actual, ok := Find(lst, func(i int) bool { return i == 2 }) + require.True(t, ok) + require.Equal(t, 2, actual) + + actual, ok = Find(lst, func(i int) bool { return i == 45 }) + require.False(t, ok) + require.Equal(t, 0, actual) +} diff --git a/time.go b/time.go new file mode 100644 index 0000000..37e93da --- /dev/null +++ b/time.go @@ -0,0 +1,46 @@ +package mango + +import ( + "fmt" + "time" +) + +const ( + DurationDay = 24 * time.Hour + DurationYear = 365 * DurationDay +) + +func FormatSimpleDate(ts *time.Time) string { + if ts == nil { + return "never" + } + return ts.Format("01-02-06") +} + +func FormatTimeSince(ts *time.Time) string { + if ts == nil { + return "never" + } + now := time.Now() + elapsed := now.Sub(*ts) + return fmt.Sprintf("%v ago", formatDuration(elapsed)) +} + +// imprecise formatting since we only care about the highest possible unit +func formatDuration(d time.Duration) string { + if d >= DurationYear { + years := d / DurationYear + return fmt.Sprintf("%dy", years) + } else if d >= DurationDay { + days := d / DurationDay + return fmt.Sprintf("%dd", days) + } else if d >= time.Hour { + hours := d / time.Hour + return fmt.Sprintf("%dh", hours) + } else if d >= time.Minute { + minutes := d / time.Minute + return fmt.Sprintf("%dm", minutes) + } + seconds := d / time.Second + return fmt.Sprintf("%ds", seconds) +} diff --git a/time_test.go b/time_test.go new file mode 100644 index 0000000..ace0199 --- /dev/null +++ b/time_test.go @@ -0,0 +1,18 @@ +package mango + +import ( + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestFormatSimpleDate(t *testing.T) { + ts := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC) + assert.Equal(t, "01-01-21", FormatSimpleDate(&ts)) +} + +func TestFormatTimeSince(t *testing.T) { + ts := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC) + timeSince := FormatTimeSince(&ts) + assert.NotEmpty(t, timeSince) +}