Files

52 lines
1.0 KiB
Go

package idgen
import (
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"inbox/internal/base/slug"
"inbox/internal/base/timeutil"
)
type Generator struct {
Clock timeutil.Clock
Random io.Reader
SuffixSize int
}
func NewGenerator(clock timeutil.Clock, random io.Reader) Generator {
if clock == nil {
clock = timeutil.SystemClock{}
}
if random == nil {
random = rand.Reader
}
return Generator{
Clock: clock,
Random: random,
SuffixSize: 6,
}
}
func (g Generator) New(kind string) (string, error) {
prefix := slug.NormalizeWithLimit(kind, 24)
if prefix == "" {
prefix = "id"
}
size := g.SuffixSize
if size <= 0 {
size = 6
}
buf := make([]byte, size)
if _, err := io.ReadFull(g.Random, buf); err != nil {
return "", fmt.Errorf("generate id suffix: %w", err)
}
return fmt.Sprintf("%s-%s-%s", prefix, timeutil.TimestampIDPart(g.Clock.Now()), hex.EncodeToString(buf)), nil
}
func New(kind string) (string, error) {
return NewGenerator(timeutil.SystemClock{}, rand.Reader).New(kind)
}