diff options
Diffstat (limited to 'is')
| -rw-r--r-- | is/comparable.go | 18 | ||||
| -rw-r--r-- | is/doc.go | 28 | ||||
| -rw-r--r-- | is/is_test.go | 61 | ||||
| -rw-r--r-- | is/ordered.go | 34 | ||||
| -rw-r--r-- | is/time.go | 34 |
5 files changed, 175 insertions, 0 deletions
diff --git a/is/comparable.go b/is/comparable.go new file mode 100644 index 0000000..7d639d8 --- /dev/null +++ b/is/comparable.go @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2025 Stefan Majewsky <majewsky@gmx.net> +// SPDX-License-Identifier: Apache-2.0 + +package is + +// EqualTo(b)(a) is the same as a == b. +func EqualTo[T comparable](rhs T) func(T) bool { + return func(lhs T) bool { + return lhs == rhs + } +} + +// DifferentFrom(b)(a) is the same as a != b. +func DifferentFrom[T comparable](rhs T) func(T) bool { + return func(lhs T) bool { + return lhs != rhs + } +} diff --git a/is/doc.go b/is/doc.go new file mode 100644 index 0000000..42af01e --- /dev/null +++ b/is/doc.go @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2025 Stefan Majewsky <majewsky@gmx.net> +// SPDX-License-Identifier: Apache-2.0 + +// Package is contains functions to express binary operations in a curried style. +// For example, "foo < bar" can be rewritten as "is.LessThan(bar)(foo)". +// +// This is not useful on its own, but may significantly improve readability +// when replacing function literals. Consider the following example: +// +// import . "github.com/majewsky/gg/option" +// +// func checkNewVolumeSize(size, usage uint64, maxSize Option[uint64]) error { +// switch { +// case size < usage: +// return errors.New("size cannot be smaller than usage") +// case maxSize.IsSomeAnd(func(value uint64) bool { return maxSize < size }): +// return errors.New("size cannot be larger than maximum") +// } +// } +// +// The IsSomeAnd() check is difficult to read because function literals in Go are clunky. +// This can be rewritten in a clearer way using is.LessThan(): +// +// // original +// case maxSize.IsSomeAnd(func(value uint64) bool { return maxSize < size }): +// // rewritten +// case maxSize.IsSomeAnd(is.LessThan(size)): +package is diff --git a/is/is_test.go b/is/is_test.go new file mode 100644 index 0000000..3c6c7db --- /dev/null +++ b/is/is_test.go @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2025 Stefan Majewsky <majewsky@gmx.net> +// SPDX-License-Identifier: Apache-2.0 + +package is_test + +import ( + "testing" + "time" + + . "github.com/majewsky/gg/internal/test" + "github.com/majewsky/gg/is" + . "github.com/majewsky/gg/option" +) + +func TestComparable(t *testing.T) { + AssertEqual(t, Some("foo").IsSomeAnd(is.EqualTo("foo")), true) + AssertEqual(t, Some("bar").IsSomeAnd(is.EqualTo("foo")), false) + + AssertEqual(t, Some("foo").IsSomeAnd(is.DifferentFrom("foo")), false) + AssertEqual(t, Some("bar").IsSomeAnd(is.DifferentFrom("foo")), true) +} + +func TestOrdered(t *testing.T) { + AssertEqual(t, Some(3).IsSomeAnd(is.Above(4)), false) + AssertEqual(t, Some(4).IsSomeAnd(is.Above(4)), false) + AssertEqual(t, Some(5).IsSomeAnd(is.Above(4)), true) + + AssertEqual(t, Some(3).IsSomeAnd(is.Below(4)), true) + AssertEqual(t, Some(4).IsSomeAnd(is.Below(4)), false) + AssertEqual(t, Some(5).IsSomeAnd(is.Below(4)), false) + + AssertEqual(t, Some(3).IsSomeAnd(is.NotAbove(4)), true) + AssertEqual(t, Some(4).IsSomeAnd(is.NotAbove(4)), true) + AssertEqual(t, Some(5).IsSomeAnd(is.NotAbove(4)), false) + + AssertEqual(t, Some(3).IsSomeAnd(is.NotBelow(4)), false) + AssertEqual(t, Some(4).IsSomeAnd(is.NotBelow(4)), true) + AssertEqual(t, Some(5).IsSomeAnd(is.NotBelow(4)), true) +} + +func TestTime(t *testing.T) { + t1 := time.Now() + t2 := t1.Add(time.Second) + t3 := t2.Add(time.Second) + + AssertEqual(t, Some(t1).IsSomeAnd(is.After(t2)), false) + AssertEqual(t, Some(t2).IsSomeAnd(is.After(t2)), false) + AssertEqual(t, Some(t3).IsSomeAnd(is.After(t2)), true) + + AssertEqual(t, Some(t1).IsSomeAnd(is.Before(t2)), true) + AssertEqual(t, Some(t2).IsSomeAnd(is.Before(t2)), false) + AssertEqual(t, Some(t3).IsSomeAnd(is.Before(t2)), false) + + AssertEqual(t, Some(t1).IsSomeAnd(is.NotAfter(t2)), true) + AssertEqual(t, Some(t2).IsSomeAnd(is.NotAfter(t2)), true) + AssertEqual(t, Some(t3).IsSomeAnd(is.NotAfter(t2)), false) + + AssertEqual(t, Some(t1).IsSomeAnd(is.NotBefore(t2)), false) + AssertEqual(t, Some(t2).IsSomeAnd(is.NotBefore(t2)), true) + AssertEqual(t, Some(t3).IsSomeAnd(is.NotBefore(t2)), true) +} diff --git a/is/ordered.go b/is/ordered.go new file mode 100644 index 0000000..79fada7 --- /dev/null +++ b/is/ordered.go @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2025 Stefan Majewsky <majewsky@gmx.net> +// SPDX-License-Identifier: Apache-2.0 + +package is + +import "cmp" + +// Above(b)(a) is the same as a > b. +func Above[T cmp.Ordered](rhs T) func(T) bool { + return func(lhs T) bool { + return lhs > rhs + } +} + +// Below(b)(a) is the same as a < b. +func Below[T cmp.Ordered](rhs T) func(T) bool { + return func(lhs T) bool { + return lhs < rhs + } +} + +// NotAbove(b)(a) is the same as a <= b. +func NotAbove[T cmp.Ordered](rhs T) func(T) bool { + return func(lhs T) bool { + return lhs <= rhs + } +} + +// NotBelow(b)(a) is the same as a >= b. +func NotBelow[T cmp.Ordered](rhs T) func(T) bool { + return func(lhs T) bool { + return lhs >= rhs + } +} diff --git a/is/time.go b/is/time.go new file mode 100644 index 0000000..3aadaf1 --- /dev/null +++ b/is/time.go @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2025 Stefan Majewsky <majewsky@gmx.net> +// SPDX-License-Identifier: Apache-2.0 + +package is + +import "time" + +// After(b)(a) is the same as a .After(b). +func After(rhs time.Time) func(time.Time) bool { + return func(lhs time.Time) bool { + return lhs.After(rhs) + } +} + +// Before(b)(a) is the same as a.Before(b). +func Before(rhs time.Time) func(time.Time) bool { + return func(lhs time.Time) bool { + return lhs.Before(rhs) + } +} + +// NotAfter(b)(a) is the same as !a.After(b). +func NotAfter(rhs time.Time) func(time.Time) bool { + return func(lhs time.Time) bool { + return !lhs.After(rhs) + } +} + +// NotBefore(b)(a) is the same as !a.Before(b). +func NotBefore(rhs time.Time) func(time.Time) bool { + return func(lhs time.Time) bool { + return !lhs.Before(rhs) + } +} |
