From 5c4e66d1443593b1446cd0b9d82be58cdd824cf3 Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Mon, 10 Mar 2025 14:25:00 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20MultiGenerator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generators.go | 27 +++++++++++++++++++++++++++ generators_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/generators.go b/generators.go index 01242fe..c409988 100644 --- a/generators.go +++ b/generators.go @@ -1,6 +1,7 @@ package nomino import ( + "errors" "time" "github.com/google/uuid" @@ -18,6 +19,32 @@ func WithGenerator(g Generator) Option { } } +// ErrMissingGenerators is returned by a multi-generator if no generators are supplied. +var ErrMissingGenerators = errors.New("no generators supplied") + +func missingGen() (string, error) { + return "", ErrMissingGenerators +} + +// MultiGeneratorInOrder allows the use of multiple generators. Each new invokation will use the next generator in turn. +// If none are passed, the generator will always return ErrMissingGenerators. +func MultiGeneratorInOrder(gens ...Generator) Generator { + if len(gens) == 0 { + return missingGen + } + + if len(gens) == 1 { + return gens[0] + } + + var idx int + return func() (string, error) { + st, err := gens[idx]() + idx = (idx + 1) % len(gens) + return st, err + } +} + func uuidGen() (string, error) { u, err := uuid.NewRandom() if err != nil { diff --git a/generators_test.go b/generators_test.go index 96759ff..210181f 100644 --- a/generators_test.go +++ b/generators_test.go @@ -18,6 +18,51 @@ func TestWithGenerator(t *testing.T) { assert.Equal(t, "abc", st) } +func TestMultiGeneratorInOrder(t *testing.T) { + st1 := "abc" + st2 := "def" + er1 := errors.New("oops") + g1 := func() (string, error) { return st1, nil } + g2 := func() (string, error) { return st2, nil } + g3 := func() (string, error) { return "", er1 } + g := MultiGeneratorInOrder(g1, g2, g3) + st, err := g() + assert.NoError(t, err) + assert.Equal(t, st1, st) + st, err = g() + assert.NoError(t, err) + assert.Equal(t, st2, st) + st, err = g() + assert.Zero(t, st) + assert.ErrorIs(t, err, er1) + st, err = g() + assert.NoError(t, err) + assert.Equal(t, st1, st) +} + +func TestMultiGeneratorInOrderOne(t *testing.T) { + st1 := "abc" + g1 := func() (string, error) { return st1, nil } + g := MultiGeneratorInOrder(g1) + + st, err := g() + assert.NoError(t, err) + assert.Equal(t, st1, st) + st, err = g() + assert.NoError(t, err) + assert.Equal(t, st1, st) +} + +func TestMultiGeneratorInOrderMissing(t *testing.T) { + g := MultiGeneratorInOrder() + st, err := g() + assert.Zero(t, st) + assert.ErrorIs(t, err, ErrMissingGenerators) + st, err = g() + assert.Zero(t, st) + assert.ErrorIs(t, err, ErrMissingGenerators) +} + func TestUUID(t *testing.T) { st, err := UUID()() assert.NoError(t, err)