Skip to content

Commit

Permalink
Add Explode and Filter to optional.Optional.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpfourny committed Jan 30, 2024
1 parent ceae0dd commit 89871f2
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 4 deletions.
36 changes: 32 additions & 4 deletions pkg/optional/optional.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ type Optional[V any] interface {

// OrElseGet returns the value contained in the Optional if the Optional is not empty, or the result of the provided function otherwise.
OrElseGet(func() V) V

// Explode returns the value contained in the Optional and an indicator of whether the Optional is empty.
// If the Optional is empty, the value returned is the zero value of type V.
Explode() (V, bool)

// Filter returns an Optional containing the value contained in the Optional if the provided predicate returns true for that value.
// If the Optional is empty, an empty Optional is returned.
Filter(func(V) bool) Optional[V]
}

// None is an Optional that represents the absence of a value.
Expand All @@ -83,6 +91,15 @@ func (n None[V]) Get() V {
return zero
}

func (n None[V]) Explode() (V, bool) {
var zero V
return zero, false
}

func (n None[V]) Filter(_ func(V) bool) Optional[V] {
return n
}

func (n None[V]) IfPresent(_ func(V)) bool {
return false
}
Expand Down Expand Up @@ -118,6 +135,21 @@ func (s Some[V]) Present() bool {
return true
}

func (s Some[V]) Get() V {
return s.Value
}

func (s Some[V]) Explode() (V, bool) {
return s.Value, true
}

func (s Some[V]) Filter(f func(V) bool) Optional[V] {
if f(s.Value) {
return s
}
return Empty[V]()
}

func (s Some[V]) IfPresent(f func(V)) bool {
f(s.Value)
return true
Expand All @@ -140,10 +172,6 @@ func (s Some[V]) OrElseGet(_ func() V) V {
return s.Value
}

func (s Some[V]) Get() V {
return s.Value
}

func (s Some[V]) String() string {
return fmt.Sprintf("Some(%#v)", s.Value)
}
65 changes: 65 additions & 0 deletions pkg/optional/optional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,71 @@ func TestMap(t *testing.T) {
})
}

func TestPresent(t *testing.T) {
t.Run("Some", func(t *testing.T) {
o := Of(42)
if !o.Present() {
t.Errorf("expected Present() to be true")
}
})

t.Run("None", func(t *testing.T) {
o := Empty[int]()
if o.Present() {
t.Errorf("expected Present() to be false")
}
})
}

func TestExplode(t *testing.T) {
t.Run("Some", func(t *testing.T) {
o := Of(42)
if v, ok := o.Explode(); !ok || v != 42 {
t.Errorf("expected Explode() to return (42, true)")
}
})

t.Run("None", func(t *testing.T) {
o := Empty[int]()
if v, ok := o.Explode(); ok || v != 0 {
t.Errorf("expected Explode() to return (0, false)")
}
})
}

func TestFilter(t *testing.T) {
t.Run("Some", func(t *testing.T) {
o := Of(42)

o2 := o.Filter(func(i int) bool { return i == 42 })
if !o2.Present() {
t.Errorf("expected Present() to be true")
}
if o2.Get() != 42 {
t.Errorf("expected Get() to return 42")
}

o3 := o.Filter(func(i int) bool { return i != 42 })
if o3.Present() {
t.Errorf("expected Present() to be false")
}
})

t.Run("None", func(t *testing.T) {
o := Empty[int]()

o2 := o.Filter(func(i int) bool { return i == 42 })
if o2.Present() {
t.Errorf("expected Present() to be false")
}

o3 := o.Filter(func(i int) bool { return i != 42 })
if o3.Present() {
t.Errorf("expected Present() to be false")
}
})
}

func TestIfPresent(t *testing.T) {
t.Run("Some", func(t *testing.T) {
var called bool
Expand Down

0 comments on commit 89871f2

Please sign in to comment.