diff options
Diffstat (limited to 'vendor/github.com/go-faker/faker/v4/pkg/options')
| -rw-r--r-- | vendor/github.com/go-faker/faker/v4/pkg/options/options.go | 346 |
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 +} |
