Skip to content

Commit

Permalink
Merge pull request #4 from xyproto/random
Browse files Browse the repository at this point in the history
Add a function for selecting a random member of an enum
  • Loading branch information
orsinium authored Aug 31, 2023
2 parents ee62a9e + f9e0128 commit 527edcb
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
20 changes: 20 additions & 0 deletions enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package enum

import (
"fmt"
"math/rand"
"strings"
"time"
)

// Member is an enum member, a specific value bound to a variable.
Expand Down Expand Up @@ -97,6 +99,24 @@ func (e Enum[M, V]) Members() []M {
return e.members
}

// Choice returns a randomly selected member of the enum.
//
// A random seed can be given (or be 0 to use time.Now().UnixNano() as the seed).
// nil is returned only if the Enum contains no members.
func (e Enum[M, V]) Choice(seed int64) *M {
lenMembers := len(e.members)
// Enum is empty
if lenMembers == 0 {
return nil
}
if seed == 0 {
seed = time.Now().UnixNano()
}
// nolint: gosec
r := rand.New(rand.NewSource(seed))
return &(e.members[r.Intn(lenMembers)])
}

// Values returns a slice of values of all members of the enum.
func (e Enum[M, V]) Values() []V {
res := make([]V, 0, len(e.members))
Expand Down
23 changes: 23 additions & 0 deletions enum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,29 @@ func TestEnum_Members(t *testing.T) {
is.Equal(Colors.Members(), exp)
}

func TestEnum_Choice(t *testing.T) {
is := is.New(t)
// Select a random color
m := Colors.Choice(0)
is.True(m != nil)
is.True(Colors.Contains(*m))
// Select a specific color using a specific random seed
m = Colors.Choice(254)
is.True(m != nil)
is.Equal(*m, Red)
// Select a specific color using a specific random seed
m = Colors.Choice(1337)
is.True(m != nil)
is.Equal(*m, Green)
// Select a specific color using a specific random seed
m = Colors.Choice(42)
is.True(m != nil)
is.Equal(*m, Blue)
// Check that selecting a random member from an empty Enum returns an error
emptyEnums := enum.New[string, Color]()
is.True(emptyEnums.Choice(0) == nil)
}

func TestEnum_Values(t *testing.T) {
is := is.New(t)
exp := []string{"red", "green", "blue"}
Expand Down

0 comments on commit 527edcb

Please sign in to comment.