package nomino import ( "errors" "math/rand" ) // Generator is a function that returns the "random" portion of the returned filename. // Technically, it doesn't necessarily need to be random, and could be based on time, or a counter, // for example. type Generator func(conf *Config) (string, error) // Make allows you to generate a new string directly from a Generator. func (g Generator) Make(opts ...Option) (string, error) { return g.MakeWithConfig(NewConfig(opts...)) } // MakeWithConfig allows you to generate a new string directly from a Generator // with a pre-existing Config. func (g Generator) MakeWithConfig(c Config) (string, error) { return Make(c.AddOptions(WithGenerator(g))) } // WithGenerator sets the specified generator func WithGenerator(g Generator) Option { return func(c *Config) { c.generator = g } } // ErrMissingGenerators is returned by a multi-generator if no generators are supplied. var ErrMissingGenerators = errors.New("no generators supplied") func missingGen(*Config) (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(c *Config) (string, error) { st, err := gens[idx](c) idx = (idx + 1) % len(gens) return st, err } } // MultiGeneratorRandomOrder allows the use of multiple generators. Each new invokation will use one of the generators randomly. // If none are passed, the generator will always return ErrMissingGenerators. func MultiGeneratorRandomOrder(gens ...Generator) Generator { if len(gens) == 0 { return missingGen } if len(gens) == 1 { return gens[0] } return func(c *Config) (string, error) { idx := rand.Int() % len(gens) return gens[idx](c) } }