github.com/ngicks/gokugen@v0.0.5/impl/repository/random_string_generator.go (about)

     1  package repository
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"encoding/hex"
     7  	"io"
     8  	"sync"
     9  )
    10  
    11  type RandStringGenerator struct {
    12  	randMu         sync.Mutex
    13  	randReader     io.Reader
    14  	byteLen        uint
    15  	bufPool        sync.Pool
    16  	encoderFactory func(r io.Writer) io.Writer
    17  }
    18  
    19  func NewRandStringGenerator(seed int64, byteLen uint, encoderFactory func(r io.Writer) io.Writer) *RandStringGenerator {
    20  	if encoderFactory == nil {
    21  		encoderFactory = hex.NewEncoder
    22  	}
    23  	return &RandStringGenerator{
    24  		randReader: rand.Reader,
    25  		byteLen:    byteLen,
    26  		bufPool: sync.Pool{
    27  			New: func() any {
    28  				buf := bytes.NewBuffer(make([]byte, 0, int(byteLen)))
    29  				return buf
    30  			},
    31  		},
    32  		encoderFactory: encoderFactory,
    33  	}
    34  }
    35  
    36  func (f *RandStringGenerator) Generate() (randomStr string, err error) {
    37  	buf := f.bufPool.Get().(*bytes.Buffer)
    38  	defer func() {
    39  		buf.Reset()
    40  		f.bufPool.Put(buf)
    41  	}()
    42  
    43  	encoder := f.encoderFactory(buf)
    44  
    45  	f.randMu.Lock()
    46  	_, err = io.CopyN(encoder, f.randReader, int64(f.byteLen))
    47  	f.randMu.Unlock()
    48  
    49  	if cl, ok := encoder.(io.Closer); ok {
    50  		cl.Close()
    51  	}
    52  
    53  	if err != nil {
    54  		return
    55  	}
    56  	return buf.String(), nil
    57  }