Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generator with options #111

Merged
merged 15 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 72 additions & 4 deletions generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import (
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000

type epochFunc func() time.Time
// EpochFunc is the function type used to provide the current time.
type EpochFunc func() time.Time

// HWAddrFunc is the function type used to provide hardware (MAC) addresses.
type HWAddrFunc func() (net.HardwareAddr, error)
Expand Down Expand Up @@ -119,13 +120,16 @@ type Gen struct {

rand io.Reader

epochFunc epochFunc
epochFunc EpochFunc
hwAddrFunc HWAddrFunc
lastTime uint64
clockSequence uint16
hardwareAddr [6]byte
}

// GenOption is a function type that can be used to configure a Gen generator.
type GenOption func(*Gen)

// interface check -- build will fail if *Gen doesn't satisfy Generator
var _ Generator = (*Gen)(nil)

Expand All @@ -147,11 +151,75 @@ func NewGen() *Gen {
// MAC address being used, you'll need to create a new generator using this
// function.
func NewGenWithHWAF(hwaf HWAddrFunc) *Gen {
return &Gen{
return NewGenWithOptions(WithHWAddrFunc(hwaf))
}

// NewGenWithOptions returns a new instance of Gen with the options provided.
// Most people should use NewGen() or NewGenWithHWAF() instead.
//
// To customize the generator, you can pass in one or more GenOption functions.
// For example:
//
// gen := NewGenWithOptions(
// WithHWAddrFunc(myHWAddrFunc),
// WithEpochFunc(myEpochFunc),
// WithRandomReader(myRandomReader),
// )
//
// NewGenWithOptions(WithHWAddrFunc(myHWAddrFunc)) is equivalent to calling
// NewGenWithHWAF(myHWAddrFunc)
// NewGenWithOptions() is equivalent to calling NewGen()
func NewGenWithOptions(opts ...GenOption) *Gen {
gen := &Gen{
epochFunc: time.Now,
hwAddrFunc: hwaf,
hwAddrFunc: defaultHWAddrFunc,
rand: rand.Reader,
}

for _, opt := range opts {
opt(gen)
}

return gen
}

// WithHWAddrFunc is a GenOption that allows you to provide your own HWAddrFunc
// function.
// When this option is nil, the defaultHWAddrFunc is used.
func WithHWAddrFunc(hwaf HWAddrFunc) GenOption {
return func(gen *Gen) {
if hwaf == nil {
hwaf = defaultHWAddrFunc
}

gen.hwAddrFunc = hwaf
LeonanCarvalho marked this conversation as resolved.
Show resolved Hide resolved
}
}

// WithEpochFunc is a GenOption that allows you to provide your own EpochFunc
// function.
// When this option is nil, time.Now is used.
func WithEpochFunc(epochf EpochFunc) GenOption {
return func(gen *Gen) {
if epochf == nil {
epochf = time.Now
}

gen.epochFunc = epochf
LeonanCarvalho marked this conversation as resolved.
Show resolved Hide resolved
}
}

// WithRandomReader is a GenOption that allows you to provide your own random
// reader.
// When this option is nil, the default rand.Reader is used.
func WithRandomReader(reader io.Reader) GenOption {
return func(gen *Gen) {
if reader == nil {
reader = rand.Reader
}

gen.rand = reader
LeonanCarvalho marked this conversation as resolved.
Show resolved Hide resolved
}
}

// NewV1 returns a UUID based on the current timestamp and MAC address.
Expand Down
Loading