summaryrefslogtreecommitdiff
path: root/vendor/github.com/go-faker/faker/v4/pkg/options/options.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/go-faker/faker/v4/pkg/options/options.go')
-rw-r--r--vendor/github.com/go-faker/faker/v4/pkg/options/options.go346
1 files changed, 346 insertions, 0 deletions
diff --git a/vendor/github.com/go-faker/faker/v4/pkg/options/options.go b/vendor/github.com/go-faker/faker/v4/pkg/options/options.go
new file mode 100644
index 0000000..3348b3e
--- /dev/null
+++ b/vendor/github.com/go-faker/faker/v4/pkg/options/options.go
@@ -0,0 +1,346 @@
+package options
+
+import (
+ "errors"
+ "fmt"
+ "math/rand"
+ "reflect"
+ "sync/atomic"
+ "time"
+ "unsafe"
+
+ fakerErrors "github.com/go-faker/faker/v4/pkg/errors"
+ "github.com/go-faker/faker/v4/pkg/interfaces"
+)
+
+var (
+ // global settings, read/write must be concurrent safe
+ generateUniqueValues atomic.Value
+ ignoreInterface atomic.Value
+ randomStringLen int32 = 25
+ lang unsafe.Pointer
+ randomMaxSize int32 = 100
+ randomMinSize int32
+ iBoundary unsafe.Pointer
+)
+
+func init() {
+ generateUniqueValues.Store(false)
+ ignoreInterface.Store(false)
+ lang = unsafe.Pointer(&interfaces.LangENG)
+ iBoundary = unsafe.Pointer(&interfaces.DefaultIntBoundary)
+}
+
+// Options represent all available option for faker.
+type Options struct {
+ // IgnoreFields used for ignoring a field when generating the fake data
+ IgnoreFields map[string]struct{}
+ // FieldProviders used for storing the custom provider function
+ FieldProviders map[string]interfaces.CustomProviderFunction
+ // StructTypeProviders used for storing the struct type of custom provider function
+ StructTypeProviders map[reflect.Type]interfaces.CustomProviderFunction
+ // MaxDepthOption used for configuring the max depth of nested identical structs for faker
+ MaxDepthOption *MaxDepthOption
+ // MaxFieldDepthOption used for configuring the max depth of fields that are filled for a struct
+ MaxFieldDepthOption int
+ // IgnoreInterface used for ignoring any interface field
+ IgnoreInterface bool
+ // StringLanguage used for setting the language for any string in faker
+ StringLanguage *interfaces.LangRuneBoundary
+ // GenerateUniqueValues to ensure the generated data is unique
+ GenerateUniqueValues bool
+ // RandomStringLength to ensure the generated string is expected as we want
+ RandomStringLength int
+ // RandomMaxSliceSize used for setting the maximum of slice size, or map size that will be generated
+ RandomMaxSliceSize int
+ // RandomMinSliceSize used for setting the minimum of slize, array, map size that will be generated
+ RandomMinSliceSize int
+ // MaxGenerateStringRetries set how much tries for generating random string
+ MaxGenerateStringRetries int
+ // SetSliceMapNilIfLenZero allows to set nil for the slice and maps, if size is 0.
+ SetSliceMapNilIfLenZero bool
+ // SetSliceMapRandomToZero sets random integer generation to zero for slice and maps
+ SetSliceMapRandomToZero bool
+ // RandomIntegerBoundary sets boundary random integer value generation. Boundaries can not exceed integer(4 byte...)
+ RandomIntegerBoundary *interfaces.RandomIntegerBoundary
+ // RandomFloatBoundary sets the boundary for random float value generation. Boundaries should comply with float values constraints (IEEE 754)
+ RandomFloatBoundary *interfaces.RandomFloatBoundary
+ // SetTagName sets the tag name that should be used
+ TagName string
+ // CustomDomain is used for specifying a custom domain when generating email
+ CustomDomain *string
+}
+
+// MaxDepthOption used for configuring the max depth of nested struct for faker
+type MaxDepthOption struct {
+ typeSeen map[reflect.Type]int
+ recursionMaxDepth int
+}
+
+func (o *MaxDepthOption) RememberType(t reflect.Type) {
+ o.typeSeen[t]++
+}
+
+func (o *MaxDepthOption) ForgetType(t reflect.Type) {
+ o.typeSeen[t]--
+}
+
+func (o *MaxDepthOption) RecursionOutOfLimit(t reflect.Type) bool {
+ return o.typeSeen[t] > o.recursionMaxDepth
+}
+
+// BuildOptions build all option functions into one option
+func BuildOptions(optFuncs []OptionFunc) *Options {
+ ops := DefaultOption()
+
+ for _, optFunc := range optFuncs {
+ optFunc(ops)
+ }
+
+ return ops
+}
+
+// DefaultOption build the default option
+func DefaultOption() *Options {
+ ops := &Options{}
+ ops.StructTypeProviders = make(map[reflect.Type]interfaces.CustomProviderFunction)
+ ops.StructTypeProviders[reflect.TypeOf(time.Time{})] = func() (interface{}, error) {
+ return time.Now().Add(time.Duration(rand.Int63())), nil
+ }
+ ops.MaxDepthOption = &MaxDepthOption{
+ typeSeen: make(map[reflect.Type]int, 1),
+ recursionMaxDepth: 1,
+ }
+ ops.MaxFieldDepthOption = -1
+ ops.GenerateUniqueValues = generateUniqueValues.Load().(bool)
+ ops.IgnoreInterface = ignoreInterface.Load().(bool)
+ ops.StringLanguage = (*interfaces.LangRuneBoundary)(atomic.LoadPointer(&lang))
+ ops.RandomStringLength = int(atomic.LoadInt32(&randomStringLen))
+ ops.RandomMaxSliceSize = int(atomic.LoadInt32(&randomMaxSize))
+ ops.RandomMinSliceSize = int(atomic.LoadInt32(&randomMinSize))
+ ops.MaxGenerateStringRetries = 1000000 //default
+ ops.RandomIntegerBoundary = (*interfaces.RandomIntegerBoundary)(atomic.LoadPointer(&iBoundary))
+ ops.RandomFloatBoundary = &interfaces.DefaultFloatBoundary
+ ops.TagName = "faker"
+ return ops
+}
+
+// OptionFunc define the options contract
+type OptionFunc func(oo *Options)
+
+// WithFieldsToIgnore used for ignoring a field when generating the fake data
+func WithFieldsToIgnore(fieldNames ...string) OptionFunc {
+ return func(oo *Options) {
+ if oo.IgnoreFields == nil {
+ oo.IgnoreFields = make(map[string]struct{}, len(fieldNames))
+ }
+ for _, f := range fieldNames {
+ oo.IgnoreFields[f] = struct{}{}
+ }
+ }
+}
+
+// WithCustomDomain is used to set a custom domain for generating fake email
+func WithCustomDomain(domain string) OptionFunc {
+ return func(oo *Options) {
+ oo.CustomDomain = &domain
+ }
+}
+
+// WithCustomFieldProvider used for storing the custom provider function
+func WithCustomFieldProvider(fieldName string, provider interfaces.CustomProviderFunction) OptionFunc {
+ return func(oo *Options) {
+ if oo.FieldProviders == nil {
+ oo.FieldProviders = make(map[string]interfaces.CustomProviderFunction, 1)
+ }
+ oo.FieldProviders[fieldName] = provider
+ }
+}
+
+// WithRecursionMaxDepth used for configuring the max depth of recursion struct for faker
+func WithRecursionMaxDepth(depth uint) OptionFunc {
+ return func(oo *Options) {
+ if oo.MaxDepthOption == nil {
+ oo.MaxDepthOption = &MaxDepthOption{
+ recursionMaxDepth: 1, // default
+ typeSeen: make(map[reflect.Type]int, 1),
+ }
+ }
+ oo.MaxDepthOption.recursionMaxDepth = int(depth)
+ }
+}
+
+// WithMaxFieldDepthOption used for configuring the max depth of fields that are filled for a struct
+func WithMaxFieldDepthOption(depth int) OptionFunc {
+ return func(oo *Options) {
+ oo.MaxFieldDepthOption = depth
+ }
+}
+
+// WithStructTypeProviders used for configuring the custom provider of struct type
+func WithStructTypeProviders(t interface{}, provider interfaces.CustomProviderFunction) OptionFunc {
+ if reflect.TypeOf(t).Kind() != reflect.Struct {
+ panic(fakerErrors.ErrOnlyStructTypeSupported)
+ }
+ return func(oo *Options) {
+ oo.StructTypeProviders[reflect.TypeOf(t)] = provider
+ }
+}
+
+// WithIgnoreInterface allows to set a flag to ignore found interface{}s.
+func WithIgnoreInterface(value bool) OptionFunc {
+ return func(oo *Options) {
+ oo.IgnoreInterface = value
+ }
+}
+
+// WithStringLanguage sets language of random string generation (LangENG, LangCHI, LangRUS, LangJPN, LangKOR, EmotEMJ)
+func WithStringLanguage(l interfaces.LangRuneBoundary) OptionFunc {
+ return func(oo *Options) {
+ oo.StringLanguage = &l
+ }
+}
+
+// WithGenerateUniqueValues allows to set the single fake data generator functions to generate unique data.
+func WithGenerateUniqueValues(unique bool) OptionFunc {
+ return func(oo *Options) {
+ oo.GenerateUniqueValues = unique
+ }
+}
+
+// WithRandomStringLength sets a length for random string generation
+func WithRandomStringLength(size uint) OptionFunc {
+ return func(oo *Options) {
+ oo.RandomStringLength = int(size)
+ }
+}
+
+// WithRandomMapAndSliceMaxSize sets the max size for maps and slices for random generation.
+func WithRandomMapAndSliceMaxSize(size uint) OptionFunc {
+ if size < 1 {
+ err := fmt.Errorf(fakerErrors.ErrSmallerThanOne, size)
+ panic(err)
+ }
+ return func(oo *Options) {
+ oo.RandomMaxSliceSize = int(size)
+ }
+}
+
+// WithRandomMapAndSliceMinSize sets the min size for maps and slices for random generation.
+func WithRandomMapAndSliceMinSize(size uint) OptionFunc {
+ return func(oo *Options) {
+ oo.RandomMinSliceSize = int(size)
+ }
+}
+
+// WithMaxGenerateStringRetries set how much tries for generating random string
+func WithMaxGenerateStringRetries(retries uint) OptionFunc {
+ return func(oo *Options) {
+ oo.MaxGenerateStringRetries = int(retries)
+ }
+}
+
+// WithNilIfLenIsZero allows to set nil for the slice and maps, if size is 0.
+func WithNilIfLenIsZero(setNil bool) OptionFunc {
+ return func(oo *Options) {
+ oo.SetSliceMapNilIfLenZero = setNil
+ }
+}
+
+// WithSliceMapRandomToZero Sets random integer generation to zero for slice and maps
+func WithSliceMapRandomToZero(setNumberToZero bool) OptionFunc {
+ return func(oo *Options) {
+ oo.SetSliceMapRandomToZero = setNumberToZero
+ }
+}
+
+// WithRandomIntegerBoundaries sets boundary random integer value generation. Boundaries can not exceed integer(4 byte...)
+func WithRandomIntegerBoundaries(boundary interfaces.RandomIntegerBoundary) OptionFunc {
+ if boundary.Start > boundary.End {
+ err := errors.New(fakerErrors.ErrStartValueBiggerThanEnd)
+ panic(err)
+ }
+ return func(oo *Options) {
+ oo.RandomIntegerBoundary = &boundary
+ }
+}
+
+// WithRandomFloatBoundaries sets the boundary for random float value generation. Boundaries should comply with float values constraints (IEEE 754)
+func WithRandomFloatBoundaries(boundary interfaces.RandomFloatBoundary) OptionFunc {
+ if boundary.Start > boundary.End {
+ err := errors.New(fakerErrors.ErrStartValueBiggerThanEnd)
+ panic(err)
+ }
+ return func(oo *Options) {
+ oo.RandomFloatBoundary = &boundary
+ }
+}
+
+// WithTagName sets the tag name to use. Default tag name is 'faker'.
+func WithTagName(tagName string) OptionFunc {
+ if tagName == "" {
+ err := errors.New(fakerErrors.ErrFieldTagIdentifierInvalid)
+ panic(err)
+ }
+ return func(oo *Options) {
+ oo.TagName = tagName
+ }
+}
+
+// SetGenerateUniqueValues allows to set the single fake data generator functions to generate unique data.
+func SetGenerateUniqueValues(unique bool) {
+ generateUniqueValues.Store(unique)
+}
+
+// SetIgnoreInterface allows to set a flag to ignore found interface{}s.
+func SetIgnoreInterface(ignore bool) {
+ ignoreInterface.Store(ignore)
+}
+
+// SetRandomStringLength sets a length for random string generation
+func SetRandomStringLength(size int) error {
+ if size < 0 {
+ return fmt.Errorf(fakerErrors.ErrSmallerThanZero, size)
+ }
+ atomic.StoreInt32(&randomStringLen, int32(size))
+ return nil
+}
+
+// SetStringLang sets language of random string generation (LangENG, LangCHI, LangRUS, LangJPN, LangKOR, EmotEMJ)
+func SetStringLang(l interfaces.LangRuneBoundary) {
+ atomic.StorePointer(&lang, unsafe.Pointer(&l))
+}
+
+// SetRandomMapAndSliceSize sets the size for maps and slices for random generation.
+// deprecates, currently left for old version usage
+func SetRandomMapAndSliceSize(size int) error {
+ return SetRandomMapAndSliceMaxSize(size)
+}
+
+// SetRandomMapAndSliceMaxSize sets the max size for maps and slices for random generation.
+func SetRandomMapAndSliceMaxSize(size int) error {
+ if size < 1 {
+ return fmt.Errorf(fakerErrors.ErrSmallerThanOne, size)
+ }
+ atomic.StoreInt32(&randomMaxSize, int32(size))
+ return nil
+}
+
+// SetRandomMapAndSliceMinSize sets the min size for maps and slices for random generation.
+func SetRandomMapAndSliceMinSize(size int) error {
+ if size < 0 {
+ return fmt.Errorf(fakerErrors.ErrSmallerThanZero, size)
+ }
+ atomic.StoreInt32(&randomMinSize, int32(size))
+ return nil
+}
+
+// SetRandomNumberBoundaries sets boundary for random number generation
+func SetRandomNumberBoundaries(start, end int) error {
+ if start > end {
+ return errors.New(fakerErrors.ErrStartValueBiggerThanEnd)
+ }
+ ptr := &interfaces.RandomIntegerBoundary{Start: start, End: end}
+ atomic.StorePointer(&iBoundary, unsafe.Pointer(ptr))
+ return nil
+}