52 lines
1.0 KiB
Go
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)
|
|
}
|