1package faker
 2
 3import (
 4	"io"
 5	mathrand "math/rand"
 6	"sync"
 7)
 8
 9var (
10	rand   *mathrand.Rand
11	crypto io.Reader
12)
13
14type safeSource struct {
15	mx sync.Mutex
16	mathrand.Source
17}
18
19func (s *safeSource) Int63() int64 {
20	s.mx.Lock()
21	defer s.mx.Unlock()
22
23	return s.Source.Int63()
24}
25
26// NewSafeSource wraps an unsafe rand.Source with a mutex to guard the random source
27// against concurrent access.
28func NewSafeSource(in mathrand.Source) mathrand.Source {
29	return &safeSource{
30		Source: in,
31	}
32}
33
34// SetRandomSource sets a new random source at the package level.
35//
36// To use a concurrent-safe source, you may wrap it with NewSafeSource,
37// e.g. SetRandomSource(NewSafeSource(mysource)).
38//
39// The default is the global, concurrent-safe source provided by math/rand.
40func SetRandomSource(in mathrand.Source) {
41	rand = mathrand.New(in)
42}
43
44// SetCryptoSource sets a new reader for functions using a cryptographically-safe random generator (e.g. UUID).
45//
46// The default is the global source provided by crypto/rand.
47func SetCryptoSource(in io.Reader) {
48	crypto = in
49}