1package faker
   2
   3// Faker is a simple fake data generator for your own struct.
   4// Save your time, and Fake your data for your testing now.
   5import (
   6	cryptorand "crypto/rand"
   7	"errors"
   8	"fmt"
   9	mathrand "math/rand"
  10	"reflect"
  11	"regexp"
  12	"strconv"
  13	"strings"
  14	"sync"
  15	"time"
  16
  17	fakerErrors "github.com/go-faker/faker/v4/pkg/errors"
  18	"github.com/go-faker/faker/v4/pkg/interfaces"
  19	"github.com/go-faker/faker/v4/pkg/options"
  20	"github.com/go-faker/faker/v4/pkg/slice"
  21)
  22
  23var (
  24	// Unique values are kept in memory so the generator retries if the value already exists
  25	uniqueValues = &sync.Map{}
  26)
  27
  28// Supported tags
  29const (
  30	letterIdxBits             = 6                    // 6 bits to represent a letter index
  31	letterIdxMask             = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
  32	letterIdxMax              = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
  33	maxRetry                  = 10000                // max number of retry for unique values
  34	keep                      = "keep"
  35	unique                    = "unique"
  36	ID                        = "uuid_digit"
  37	HyphenatedID              = "uuid_hyphenated"
  38	EmailTag                  = "email"
  39	MacAddressTag             = "mac_address"
  40	DomainNameTag             = "domain_name"
  41	UserNameTag               = "username"
  42	URLTag                    = "url"
  43	IPV4Tag                   = "ipv4"
  44	IPV6Tag                   = "ipv6"
  45	PASSWORD                  = "password"
  46	JWT                       = "jwt"
  47	LATITUDE                  = "lat"
  48	LONGITUDE                 = "long"
  49	RealAddressTag            = "real_address"
  50	CreditCardNumber          = "cc_number"
  51	CreditCardType            = "cc_type"
  52	PhoneNumber               = "phone_number"
  53	TollFreeNumber            = "toll_free_number"
  54	E164PhoneNumberTag        = "e_164_phone_number"
  55	TitleMaleTag              = "title_male"
  56	TitleFemaleTag            = "title_female"
  57	FirstNameTag              = "first_name"
  58	FirstNameMaleTag          = "first_name_male"
  59	FirstNameFemaleTag        = "first_name_female"
  60	LastNameTag               = "last_name"
  61	NAME                      = "name"
  62	ChineseFirstNameTag       = "chinese_first_name"
  63	ChineseLastNameTag        = "chinese_last_name"
  64	ChineseNameTag            = "chinese_name"
  65	GENDER                    = "gender"
  66	UnixTimeTag               = "unix_time"
  67	DATE                      = "date"
  68	TIME                      = "time"
  69	MonthNameTag              = "month_name"
  70	YEAR                      = "year"
  71	DayOfWeekTag              = "day_of_week"
  72	DayOfMonthTag             = "day_of_month"
  73	TIMESTAMP                 = "timestamp"
  74	CENTURY                   = "century"
  75	TIMEZONE                  = "timezone"
  76	TimePeriodTag             = "time_period"
  77	WORD                      = "word"
  78	SENTENCE                  = "sentence"
  79	PARAGRAPH                 = "paragraph"
  80	CurrencyTag               = "currency"
  81	AmountTag                 = "amount"
  82	AmountWithCurrencyTag     = "amount_with_currency"
  83	SKIP                      = "-"
  84	Length                    = "len"
  85	SliceLength               = "slice_len"
  86	Language                  = "lang"
  87	BoundaryStart             = "boundary_start"
  88	BoundaryEnd               = "boundary_end"
  89	Equals                    = "="
  90	comma                     = ","
  91	colon                     = ":"
  92	ONEOF                     = "oneof"
  93	RussianFirstNameMaleTag   = "russian_first_name_male"
  94	RussianLastNameMaleTag    = "russian_last_name_male"
  95	RussianFirstNameFemaleTag = "russian_first_name_female"
  96	RussianLastNameFemaleTag  = "russian_last_name_female"
  97	BloodTypeTag              = "blood_type"
  98	CountryInfoTag            = "country_info"
  99	UserAgentTag              = "user_agent"
 100)
 101
 102// PriorityTags define the priority order of the tag
 103var PriorityTags = []string{ID, HyphenatedID, EmailTag, MacAddressTag, DomainNameTag, UserNameTag, URLTag, IPV4Tag,
 104	IPV6Tag, PASSWORD, JWT, CountryInfoTag, LATITUDE, LONGITUDE, CreditCardNumber, CreditCardType, PhoneNumber, TollFreeNumber,
 105	E164PhoneNumberTag, TitleMaleTag, TitleFemaleTag, FirstNameTag, FirstNameMaleTag, FirstNameFemaleTag, LastNameTag,
 106	NAME, ChineseFirstNameTag, ChineseLastNameTag, ChineseNameTag, GENDER, UnixTimeTag, DATE, TIME, MonthNameTag,
 107	YEAR, DayOfWeekTag, DayOfMonthTag, TIMESTAMP, CENTURY, TIMEZONE, TimePeriodTag, WORD, SENTENCE, PARAGRAPH,
 108	CurrencyTag, AmountTag, AmountWithCurrencyTag, SKIP, Length, SliceLength, Language, BoundaryStart, BoundaryEnd, ONEOF, BloodTypeTag,
 109	UserAgentTag,
 110}
 111
 112type mapperTagCustom struct {
 113	sync.Map
 114}
 115
 116func (m *mapperTagCustom) Load(key string) (interfaces.TaggedFunction, bool) {
 117	mappedTagFunc, ok := m.Map.Load(key)
 118	if !ok {
 119		return nil, ok
 120	}
 121	tagFunc, ok := mappedTagFunc.(interfaces.TaggedFunction)
 122	if ok {
 123		return tagFunc, ok
 124	}
 125	tagPureFunc, ok := mappedTagFunc.(func(v reflect.Value) (interface{}, error))
 126	if ok {
 127		return tagPureFunc, ok
 128	}
 129	return nil, false
 130}
 131
 132func (m *mapperTagCustom) Store(key string, taggedFunc interfaces.TaggedFunction) {
 133	m.Map.Store(key, taggedFunc)
 134}
 135
 136var defaultTag = sync.Map{}
 137
 138func initDefaultTag() {
 139	defaultTag.Store(BloodTypeTag, BloodTypeTag)
 140	defaultTag.Store(EmailTag, EmailTag)
 141	defaultTag.Store(MacAddressTag, MacAddressTag)
 142	defaultTag.Store(DomainNameTag, DomainNameTag)
 143	defaultTag.Store(URLTag, URLTag)
 144	defaultTag.Store(UserNameTag, UserNameTag)
 145	defaultTag.Store(IPV4Tag, IPV4Tag)
 146	defaultTag.Store(IPV6Tag, IPV6Tag)
 147	defaultTag.Store(PASSWORD, PASSWORD)
 148	defaultTag.Store(JWT, JWT)
 149	defaultTag.Store(CreditCardType, CreditCardType)
 150	defaultTag.Store(CreditCardNumber, CreditCardNumber)
 151	defaultTag.Store(CountryInfoTag, CountryInfoTag)
 152	defaultTag.Store(LATITUDE, LATITUDE)
 153	defaultTag.Store(LONGITUDE, LONGITUDE)
 154	defaultTag.Store(RealAddressTag, RealAddressTag)
 155	defaultTag.Store(PhoneNumber, PhoneNumber)
 156	defaultTag.Store(TollFreeNumber, TollFreeNumber)
 157	defaultTag.Store(E164PhoneNumberTag, E164PhoneNumberTag)
 158	defaultTag.Store(TitleMaleTag, TitleMaleTag)
 159	defaultTag.Store(TitleFemaleTag, TitleFemaleTag)
 160	defaultTag.Store(FirstNameTag, FirstNameTag)
 161	defaultTag.Store(FirstNameMaleTag, FirstNameMaleTag)
 162	defaultTag.Store(FirstNameFemaleTag, FirstNameFemaleTag)
 163	defaultTag.Store(LastNameTag, LastNameTag)
 164	defaultTag.Store(NAME, NAME)
 165	defaultTag.Store(ChineseFirstNameTag, ChineseFirstNameTag)
 166	defaultTag.Store(ChineseLastNameTag, ChineseLastNameTag)
 167	defaultTag.Store(ChineseNameTag, ChineseNameTag)
 168	defaultTag.Store(GENDER, GENDER)
 169	defaultTag.Store(UnixTimeTag, UnixTimeTag)
 170	defaultTag.Store(DATE, DATE)
 171	defaultTag.Store(TIME, TimeFormat)
 172	defaultTag.Store(MonthNameTag, MonthNameTag)
 173	defaultTag.Store(YEAR, YearFormat)
 174	defaultTag.Store(DayOfWeekTag, DayOfWeekTag)
 175	defaultTag.Store(DayOfMonthTag, DayOfMonthFormat)
 176	defaultTag.Store(TIMESTAMP, TIMESTAMP)
 177	defaultTag.Store(CENTURY, CENTURY)
 178	defaultTag.Store(TIMEZONE, TIMEZONE)
 179	defaultTag.Store(TimePeriodTag, TimePeriodFormat)
 180	defaultTag.Store(WORD, WORD)
 181	defaultTag.Store(SENTENCE, SENTENCE)
 182	defaultTag.Store(PARAGRAPH, PARAGRAPH)
 183	defaultTag.Store(CurrencyTag, CurrencyTag)
 184	defaultTag.Store(AmountTag, AmountTag)
 185	defaultTag.Store(AmountWithCurrencyTag, AmountWithCurrencyTag)
 186	defaultTag.Store(ID, ID)
 187	defaultTag.Store(HyphenatedID, HyphenatedID)
 188	defaultTag.Store(RussianFirstNameMaleTag, RussianFirstNameMaleTag)
 189	defaultTag.Store(RussianLastNameMaleTag, RussianLastNameMaleTag)
 190	defaultTag.Store(RussianFirstNameFemaleTag, RussianFirstNameFemaleTag)
 191	defaultTag.Store(RussianLastNameFemaleTag, RussianLastNameFemaleTag)
 192	defaultTag.Store(UserAgentTag, UserAgentTag)
 193}
 194
 195var mapperTag = mapperTagCustom{}
 196
 197func initMapperTagDefault() {
 198	mapperTag.Store(CreditCardType, GetPayment().CreditCardType)
 199	mapperTag.Store(CreditCardNumber, GetPayment().CreditCardNumber)
 200	mapperTag.Store(CountryInfoTag, GetAddress().CountryInfo)
 201	mapperTag.Store(LATITUDE, GetAddress().Latitude)
 202	mapperTag.Store(LONGITUDE, GetAddress().Longitude)
 203	mapperTag.Store(RealAddressTag, GetAddress().RealWorld)
 204	mapperTag.Store(PhoneNumber, GetPhoner().PhoneNumber)
 205	mapperTag.Store(TollFreeNumber, GetPhoner().TollFreePhoneNumber)
 206	mapperTag.Store(E164PhoneNumberTag, GetPhoner().E164PhoneNumber)
 207	mapperTag.Store(TitleMaleTag, GetPerson().TitleMale)
 208	mapperTag.Store(TitleFemaleTag, GetPerson().TitleFeMale)
 209	mapperTag.Store(FirstNameTag, GetPerson().FirstName)
 210	mapperTag.Store(FirstNameMaleTag, GetPerson().FirstNameMale)
 211	mapperTag.Store(FirstNameFemaleTag, GetPerson().FirstNameFemale)
 212	mapperTag.Store(LastNameTag, GetPerson().LastName)
 213	mapperTag.Store(NAME, GetPerson().Name)
 214	mapperTag.Store(ChineseFirstNameTag, GetPerson().ChineseFirstName)
 215	mapperTag.Store(ChineseLastNameTag, GetPerson().ChineseLastName)
 216	mapperTag.Store(ChineseNameTag, GetPerson().ChineseName)
 217	mapperTag.Store(GENDER, GetPerson().Gender)
 218	mapperTag.Store(UnixTimeTag, GetDateTimer().UnixTime)
 219	mapperTag.Store(DATE, GetDateTimer().Date)
 220	mapperTag.Store(TIME, GetDateTimer().Time)
 221	mapperTag.Store(MonthNameTag, GetDateTimer().MonthName)
 222	mapperTag.Store(YEAR, GetDateTimer().Year)
 223	mapperTag.Store(DayOfWeekTag, GetDateTimer().DayOfWeek)
 224	mapperTag.Store(DayOfMonthTag, GetDateTimer().DayOfMonth)
 225	mapperTag.Store(TIMESTAMP, GetDateTimer().Timestamp)
 226	mapperTag.Store(CENTURY, GetDateTimer().Century)
 227	mapperTag.Store(TIMEZONE, GetDateTimer().TimeZone)
 228	mapperTag.Store(TimePeriodTag, GetDateTimer().TimePeriod)
 229	mapperTag.Store(WORD, GetLorem().Word)
 230	mapperTag.Store(SENTENCE, GetLorem().Sentence)
 231	mapperTag.Store(PARAGRAPH, GetLorem().Paragraph)
 232	mapperTag.Store(CurrencyTag, GetPrice().Currency)
 233	mapperTag.Store(AmountTag, GetPrice().Amount)
 234	mapperTag.Store(AmountWithCurrencyTag, GetPrice().AmountWithCurrency)
 235	mapperTag.Store(ID, GetIdentifier().Digit)
 236	mapperTag.Store(HyphenatedID, GetIdentifier().Hyphenated)
 237	mapperTag.Store(RussianFirstNameMaleTag, GetPerson().RussianFirstNameMale)
 238	mapperTag.Store(RussianFirstNameFemaleTag, GetPerson().RussianFirstNameFemale)
 239	mapperTag.Store(RussianLastNameMaleTag, GetPerson().RussianLastNameMale)
 240	mapperTag.Store(RussianLastNameFemaleTag, GetPerson().RussianLastNameFemale)
 241	mapperTag.Store(BloodTypeTag, GetBlood().BloodGroup)
 242	mapperTag.Store(UserAgentTag, GetUserAgent().UserAgent)
 243}
 244
 245// Compiled regexp
 246var (
 247	findLangReg     *regexp.Regexp
 248	findLenReg      *regexp.Regexp
 249	findSliceLenReg *regexp.Regexp
 250)
 251
 252func init() {
 253	rand = mathrand.New(NewSafeSource(mathrand.NewSource(time.Now().UnixNano())))
 254	crypto = cryptorand.Reader
 255}
 256
 257func init() {
 258	findLangReg, _ = regexp.Compile("lang=[a-z]{3}")
 259	findLenReg, _ = regexp.Compile(`len=\d+`)
 260	findSliceLenReg, _ = regexp.Compile(`slice_len=\d+`)
 261
 262	randNameFlag = rand.Intn(100) // for person
 263}
 264
 265func init() {
 266	initDefaultTag()
 267	initMapperTagDefault()
 268}
 269
 270// ResetUnique is used to forget generated unique values.
 271// Call this when you're done generating a dataset.
 272func ResetUnique() {
 273	uniqueValues = &sync.Map{}
 274}
 275
 276var (
 277	SetGenerateUniqueValues     = options.SetGenerateUniqueValues
 278	SetIgnoreInterface          = options.SetIgnoreInterface
 279	SetRandomStringLength       = options.SetRandomStringLength
 280	SetStringLang               = options.SetStringLang
 281	SetRandomMapAndSliceSize    = options.SetRandomMapAndSliceSize
 282	SetRandomMapAndSliceMaxSize = options.SetRandomMapAndSliceMaxSize
 283	SetRandomMapAndSliceMinSize = options.SetRandomMapAndSliceMinSize
 284	SetRandomNumberBoundaries   = options.SetRandomNumberBoundaries
 285)
 286
 287func initMapperTagWithOption(opts ...options.OptionFunc) {
 288	mapperTag.Store(EmailTag, GetNetworker(opts...).Email)
 289	mapperTag.Store(MacAddressTag, GetNetworker(opts...).MacAddress)
 290	mapperTag.Store(DomainNameTag, GetNetworker(opts...).DomainName)
 291	mapperTag.Store(URLTag, GetNetworker(opts...).URL)
 292	mapperTag.Store(UserNameTag, GetNetworker(opts...).UserName)
 293	mapperTag.Store(IPV4Tag, GetNetworker(opts...).IPv4)
 294	mapperTag.Store(IPV6Tag, GetNetworker(opts...).IPv6)
 295	mapperTag.Store(PASSWORD, GetNetworker(opts...).Password)
 296	mapperTag.Store(JWT, GetNetworker(opts...).Jwt)
 297}
 298
 299func initOption(opt ...options.OptionFunc) *options.Options {
 300	opts := options.BuildOptions(opt)
 301	initMapperTagWithOption(opt...)
 302	return opts
 303}
 304
 305// FakeData is the main function. Will generate a fake data based on your struct.  You can use this for automation testing, or anything that need automated data.
 306// You don't need to Create your own data for your testing.
 307func FakeData(a interface{}, opt ...options.OptionFunc) error {
 308	opts := initOption(opt...)
 309	reflectType := reflect.TypeOf(a)
 310
 311	if reflectType.Kind() != reflect.Ptr {
 312		return errors.New(fakerErrors.ErrValueNotPtr)
 313	}
 314
 315	if reflect.ValueOf(a).IsNil() {
 316		return fmt.Errorf(fakerErrors.ErrNotSupportedPointer, reflectType.Elem().String())
 317	}
 318
 319	rval := reflect.ValueOf(a)
 320	finalValue, err := getFakedValue(a, opts)
 321	if err != nil {
 322		return err
 323	}
 324
 325	if rval.Elem().CanSet() && rval.Elem().
 326		CanConvert(reflectType.Elem()) {
 327		rval.Elem().Set(finalValue.Elem().
 328			Convert(reflectType.Elem()))
 329	}
 330	return nil
 331}
 332
 333// AddProvider extend faker with tag to generate fake data with specified custom algorithm
 334// Example:
 335//
 336//	type Gondoruwo struct {
 337//		Name       string
 338//		Locatadata int
 339//	}
 340//
 341//	type Sample struct {
 342//		ID                 int64     `faker:"customIdFaker"`
 343//		Gondoruwo          Gondoruwo `faker:"gondoruwo"`
 344//		Danger             string    `faker:"danger"`
 345//	}
 346//
 347//	func CustomGenerator() {
 348//		// explicit
 349//		faker.AddProvider("customIdFaker", func(v reflect.Value) (interface{}, error) {
 350//		 	return int64(43), nil
 351//		})
 352//		// functional
 353//		faker.AddProvider("danger", func() faker.TaggedFunction {
 354//			return func(v reflect.Value) (interface{}, error) {
 355//				return "danger-ranger", nil
 356//			}
 357//		}())
 358//		faker.AddProvider("gondoruwo", func(v reflect.Value) (interface{}, error) {
 359//			obj := Gondoruwo{
 360//				Name:       "Power",
 361//				Locatadata: 324,
 362//			}
 363//			return obj, nil
 364//		})
 365//	}
 366//
 367//	func main() {
 368//		CustomGenerator()
 369//		var sample Sample
 370//		faker.FakeData(&sample)
 371//		fmt.Printf("%+v", sample)
 372//	}
 373//
 374// Will print
 375//
 376//	{ID:43 Gondoruwo:{Name:Power Locatadata:324} Danger:danger-ranger}
 377//
 378// Notes: when using a custom provider make sure to return the same type as the field
 379func AddProvider(tag string, provider interfaces.TaggedFunction) error {
 380	if _, ok := mapperTag.Load(tag); ok {
 381		return errors.New(fakerErrors.ErrTagAlreadyExists)
 382	}
 383	PriorityTags = append(PriorityTags, tag)
 384	mapperTag.Store(tag, provider)
 385
 386	return nil
 387}
 388
 389// RemoveProvider removes existing customization added with AddProvider
 390func RemoveProvider(tag string) error {
 391	if _, ok := mapperTag.Load(tag); !ok {
 392		return errors.New(fakerErrors.ErrTagDoesNotExist)
 393	}
 394	mapperTag.Delete(tag)
 395	return nil
 396}
 397
 398func getFakedValue(item interface{}, opts *options.Options) (reflect.Value, error) {
 399	t := reflect.TypeOf(item)
 400	if t == nil {
 401		if opts.IgnoreInterface {
 402			return reflect.ValueOf(nil), nil
 403		}
 404		return reflect.Value{}, fmt.Errorf("interface{} not allowed")
 405	}
 406	if opts.MaxDepthOption.RecursionOutOfLimit(t) {
 407		return reflect.Zero(t), nil
 408	}
 409	opts.MaxDepthOption.RememberType(t)
 410	defer func() {
 411		opts.MaxDepthOption.ForgetType(t)
 412	}()
 413	k := t.Kind()
 414	switch k {
 415	case reflect.Ptr:
 416		v := reflect.New(t.Elem())
 417		var val reflect.Value
 418		var err error
 419		if item != reflect.Zero(reflect.TypeOf(item)).Interface() {
 420			val, err = getFakedValue(reflect.ValueOf(item).Elem().Interface(), opts)
 421
 422		} else {
 423			val, err = getFakedValue(v.Elem().Interface(), opts)
 424		}
 425		if err != nil {
 426			return reflect.Value{}, err
 427		}
 428
 429		if reflect.ValueOf(val).IsZero() {
 430			return v, nil
 431		}
 432
 433		if v.Elem().CanSet() && v.Elem().CanConvert(t.Elem()) {
 434			v.Elem().Set(val.Convert(t.Elem()))
 435		}
 436		return v, nil
 437	case reflect.Struct:
 438		if structTypeProvider, f := opts.StructTypeProviders[t]; f {
 439			ft, err := structTypeProvider()
 440			return reflect.ValueOf(ft), err
 441		}
 442		originalDataVal := reflect.ValueOf(item)
 443		v := reflect.New(t).Elem()
 444		if opts.MaxFieldDepthOption == 0 {
 445			return v, nil
 446		} else if opts.MaxFieldDepthOption > 0 {
 447			opts.MaxFieldDepthOption--
 448			defer func() { opts.MaxFieldDepthOption++ }()
 449		}
 450		retry := 0 // error if cannot generate unique value after maxRetry tries
 451		for i := 0; i < v.NumField(); i++ {
 452			if !v.Field(i).CanSet() {
 453				continue // to avoid panic to set on unexported field in struct
 454			}
 455
 456			if _, ok := opts.IgnoreFields[t.Field(i).Name]; ok {
 457				continue
 458			}
 459
 460			if p, ok := opts.FieldProviders[t.Field(i).Name]; ok {
 461				val, err := p()
 462				if err != nil {
 463					return reflect.Value{}, fmt.Errorf("custom provider for field %s: %w", t.Field(i).Name, err)
 464				}
 465				v.Field(i).Set(reflect.ValueOf(val))
 466				continue
 467			}
 468
 469			tags := decodeTags(t, i, opts.TagName)
 470			switch {
 471			case tags.keepOriginal:
 472				zero, err := isZero(reflect.ValueOf(item).Field(i))
 473				if err != nil {
 474					return reflect.Value{}, err
 475				}
 476				if zero {
 477					err := setDataWithTag(v.Field(i).Addr(), tags.fieldType, *opts)
 478					if err != nil {
 479						return reflect.Value{}, err
 480					}
 481					continue
 482				}
 483				v.Field(i).Set(reflect.ValueOf(item).Field(i))
 484			case tags.fieldType == "":
 485				val, err := getFakedValue(v.Field(i).Interface(), opts)
 486				if err != nil {
 487					return reflect.Value{}, err
 488				}
 489
 490				if v.Field(i).CanSet() {
 491					if !reflect.ValueOf(val).IsZero() && val.CanConvert(v.Field(i).Type()) {
 492						val = val.Convert(v.Field(i).Type())
 493						v.Field(i).Set(val)
 494					}
 495
 496				}
 497			case tags.fieldType == SKIP:
 498				data := originalDataVal.Field(i).Interface()
 499				if v.CanSet() && data != nil {
 500					v.Field(i).Set(reflect.ValueOf(data))
 501				}
 502			default:
 503				err := setDataWithTag(v.Field(i).Addr(), tags.fieldType, *opts)
 504				if err != nil {
 505					return reflect.Value{}, err
 506				}
 507			}
 508
 509			if tags.unique {
 510				if retry >= maxRetry {
 511					return reflect.Value{}, fmt.Errorf(fakerErrors.ErrUniqueFailure, reflect.TypeOf(item).Field(i).Name)
 512				}
 513				value := v.Field(i).Interface()
 514				uniqueVal, _ := uniqueValues.Load(tags.fieldType)
 515				uniqueValArr, _ := uniqueVal.([]interface{})
 516				if slice.ContainsValue(uniqueValArr, value) { // Retry if unique value already found
 517					i--
 518					retry++
 519					continue
 520				}
 521				retry = 0
 522				uniqueValues.Store(tags.fieldType, append(uniqueValArr, value))
 523			} else {
 524				retry = 0
 525			}
 526
 527		}
 528		return v, nil
 529
 530	case reflect.String:
 531		res, err := randomString(opts.RandomStringLength, *opts)
 532		return reflect.ValueOf(res), err
 533	case reflect.Slice:
 534
 535		length := randomSliceAndMapSize(*opts)
 536		if opts.SetSliceMapNilIfLenZero && length == 0 {
 537			return reflect.Zero(t), nil
 538		}
 539		v := reflect.MakeSlice(t, length, length)
 540		for i := 0; i < length; i++ {
 541			val, err := getFakedValue(v.Index(i).Interface(), opts)
 542			if err != nil {
 543				return reflect.Value{}, err
 544			}
 545			// if the value generated is NIL/Zero
 546			// it will kept it as nil
 547			if reflect.ValueOf(val).IsZero() {
 548				continue
 549			}
 550			if val.CanConvert(v.Index(i).Type()) {
 551				val = val.Convert(v.Index(i).Type())
 552				v.Index(i).Set(val)
 553			}
 554		}
 555		return v, nil
 556	case reflect.Array:
 557		v := reflect.New(t).Elem()
 558		for i := 0; i < v.Len(); i++ {
 559			val, err := getFakedValue(v.Index(i).Interface(), opts)
 560			if err != nil {
 561				return reflect.Value{}, err
 562			}
 563			if reflect.ValueOf(val).IsZero() {
 564				continue
 565			}
 566			if val.CanConvert(v.Index(i).Type()) {
 567				val = val.Convert(v.Index(i).Type())
 568			}
 569			v.Index(i).Set(val)
 570		}
 571		return v, nil
 572	case reflect.Int:
 573		return reflect.ValueOf(randomInteger(opts)), nil
 574	case reflect.Int8:
 575		return reflect.ValueOf(int8(randomInteger(opts))), nil
 576	case reflect.Int16:
 577		return reflect.ValueOf(int16(randomInteger(opts))), nil
 578	case reflect.Int32:
 579		return reflect.ValueOf(int32(randomInteger(opts))), nil
 580	case reflect.Int64:
 581		return reflect.ValueOf(int64(randomInteger(opts))), nil
 582	case reflect.Float32:
 583		return reflect.ValueOf(float32(randomFloat(opts))), nil
 584	case reflect.Float64:
 585		return reflect.ValueOf(randomFloat(opts)), nil
 586	case reflect.Bool:
 587		val := rand.Intn(2) > 0
 588		return reflect.ValueOf(val), nil
 589
 590	case reflect.Uint:
 591		return reflect.ValueOf(uint(randomInteger(opts))), nil
 592
 593	case reflect.Uint8:
 594		return reflect.ValueOf(uint8(randomInteger(opts))), nil
 595
 596	case reflect.Uint16:
 597		return reflect.ValueOf(uint16(randomInteger(opts))), nil
 598
 599	case reflect.Uint32:
 600		return reflect.ValueOf(uint32(randomInteger(opts))), nil
 601
 602	case reflect.Uint64:
 603		return reflect.ValueOf(uint64(randomInteger(opts))), nil
 604
 605	case reflect.Map:
 606		length := randomSliceAndMapSize(*opts)
 607		if opts.SetSliceMapNilIfLenZero && length == 0 {
 608			return reflect.Zero(t), nil
 609		}
 610		v := reflect.MakeMap(t)
 611		for i := 0; i < length; i++ {
 612			keyInstance := reflect.New(t.Key()).Elem().Interface()
 613			key, err := getFakedValue(keyInstance, opts)
 614			if err != nil {
 615				return reflect.Value{}, err
 616			}
 617
 618			valueInstance := reflect.New(t.Elem()).Elem().Interface()
 619			val, err := getFakedValue(valueInstance, opts)
 620			if err != nil {
 621				return reflect.Value{}, err
 622			}
 623
 624			keyIsZero := reflect.ValueOf(key).IsZero()
 625			valIsZero := reflect.ValueOf(val).IsZero()
 626
 627			if keyIsZero || valIsZero {
 628				continue
 629			}
 630			key = key.Convert(t.Key())
 631			val = val.Convert(v.Type().Elem())
 632			v.SetMapIndex(key, val)
 633		}
 634		return v, nil
 635	default:
 636		err := fmt.Errorf("no support for kind %+v", t)
 637		return reflect.Value{}, err
 638	}
 639
 640}
 641
 642func isZero(field reflect.Value) (bool, error) {
 643	if field.Kind() == reflect.Map {
 644		return field.Len() == 0, nil
 645	}
 646
 647	for _, kind := range []reflect.Kind{reflect.Struct, reflect.Slice, reflect.Array} {
 648		if kind == field.Kind() {
 649			return false, fmt.Errorf("keep not allowed on struct")
 650		}
 651	}
 652	return reflect.Zero(field.Type()).Interface() == field.Interface(), nil
 653}
 654
 655func decodeTags(typ reflect.Type, i int, tagName string) structTag {
 656	tagField := typ.Field(i).Tag.Get(tagName)
 657	tags := strings.Split(tagField, ",")
 658
 659	keepOriginal := false
 660	uni := false
 661	res := make([]string, 0)
 662	pMap := make(map[string]string)
 663	for _, tag := range tags {
 664		if tag == keep {
 665			keepOriginal = true
 666			continue
 667		} else if tag == unique {
 668			uni = true
 669			continue
 670		}
 671		// res = append(res, tag)
 672		ptag := strings.ToLower(strings.Trim(strings.Split(tag, "=")[0], " "))
 673		pMap[ptag] = tag
 674		ptag = strings.ToLower(strings.Trim(strings.Split(tag, ":")[0], " "))
 675		pMap[ptag] = tag
 676	}
 677	// Priority
 678	for _, ptag := range PriorityTags {
 679		if tag, ok := pMap[ptag]; ok {
 680			if ptag == ONEOF {
 681				res = append(res, tags...)
 682			} else {
 683				res = append(res, tag)
 684			}
 685			delete(pMap, ptag)
 686		}
 687	}
 688	// custom,keep,unique
 689	if len(res) < 1 {
 690		if !keepOriginal && !uni {
 691			res = append(res, tags...)
 692		}
 693	}
 694
 695	return structTag{
 696		fieldType:    strings.Join(res, ","),
 697		unique:       uni,
 698		keepOriginal: keepOriginal,
 699	}
 700}
 701
 702type structTag struct {
 703	fieldType    string
 704	unique       bool
 705	keepOriginal bool
 706}
 707
 708func setDataWithTag(v reflect.Value, tag string, opt options.Options) error {
 709	if v.Kind() != reflect.Ptr {
 710		return errors.New(fakerErrors.ErrValueNotPtr)
 711	}
 712	v = reflect.Indirect(v)
 713	switch v.Kind() {
 714	case reflect.Ptr:
 715		if _, exist := mapperTag.Load(tag); !exist {
 716			newv := reflect.New(v.Type().Elem())
 717			if err := setDataWithTag(newv, tag, opt); err != nil {
 718				return err
 719			}
 720			v.Set(newv)
 721			return nil
 722		}
 723		if _, def := defaultTag.Load(tag); !def {
 724			tagFunc, ok := mapperTag.Load(tag)
 725			if !ok {
 726				return fmt.Errorf(fakerErrors.ErrTagNotSupported, tag)
 727			}
 728			res, err := tagFunc(v)
 729			if err != nil {
 730				return err
 731			}
 732			v.Set(reflect.ValueOf(res))
 733			return nil
 734		}
 735
 736		t := v.Type()
 737		newv := reflect.New(t.Elem())
 738		tagFunc, ok := mapperTag.Load(tag)
 739		if !ok {
 740			return fmt.Errorf(fakerErrors.ErrTagNotSupported, tag)
 741		}
 742		res, err := tagFunc(newv.Elem())
 743		if err != nil {
 744			return err
 745		}
 746		rval := reflect.ValueOf(res)
 747		newv.Elem().Set(rval)
 748		v.Set(newv)
 749		return nil
 750	case reflect.String:
 751		return userDefinedString(v, tag, opt)
 752	case reflect.Int, reflect.Int32, reflect.Int64, reflect.Int8, reflect.Int16, reflect.Uint, reflect.Uint8,
 753		reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:
 754		return userDefinedNumber(v, tag)
 755	case reflect.Slice, reflect.Array:
 756		return userDefinedArray(v, tag, opt)
 757	case reflect.Map:
 758		return userDefinedMap(v, tag, opt)
 759	default:
 760		tagFunc, ok := mapperTag.Load(tag)
 761		if !ok {
 762			return fmt.Errorf(fakerErrors.ErrTagNotSupported, tag)
 763		}
 764		res, err := tagFunc(v)
 765		if err != nil {
 766			return err
 767		}
 768		v.Set(reflect.ValueOf(res))
 769	}
 770	return nil
 771}
 772
 773func userDefinedMap(v reflect.Value, tag string, opt options.Options) error {
 774	if tagFunc, ok := mapperTag.Load(tag); ok {
 775		res, err := tagFunc(v)
 776		if err != nil {
 777			return err
 778		}
 779
 780		v.Set(reflect.ValueOf(res))
 781		return nil
 782	}
 783
 784	length := randomSliceAndMapSize(opt)
 785	if opt.SetSliceMapNilIfLenZero && length == 0 {
 786		v.Set(reflect.Zero(v.Type()))
 787		return nil
 788	}
 789	definedMap := reflect.MakeMap(v.Type())
 790	for i := 0; i < length; i++ {
 791		key, err := getValueWithTag(v.Type().Key(), tag, opt)
 792		if err != nil {
 793			return err
 794		}
 795		val, err := getValueWithTag(v.Type().Elem(), tag, opt)
 796		if err != nil {
 797			return err
 798		}
 799		definedMap.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(val))
 800	}
 801	v.Set(definedMap)
 802	return nil
 803}
 804
 805func getValueWithTag(t reflect.Type, tag string, opt options.Options) (interface{}, error) {
 806	switch t.Kind() {
 807	case reflect.Int, reflect.Int32, reflect.Int64, reflect.Int8, reflect.Int16, reflect.Uint, reflect.Uint8,
 808		reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:
 809		res, err := extractNumberFromTag(tag, t)
 810		if err != nil {
 811			return nil, err
 812		}
 813		return res, nil
 814	case reflect.String:
 815		res, err := extractStringFromTag(tag, opt)
 816		if err != nil {
 817			return nil, err
 818		}
 819		return res, nil
 820	default:
 821		return 0, errors.New(fakerErrors.ErrUnknownType)
 822	}
 823}
 824
 825func getNumberWithBoundary(t reflect.Type, boundary interfaces.RandomIntegerBoundary) (interface{}, error) {
 826	switch t.Kind() {
 827	case reflect.Uint:
 828		return uint(randomIntegerWithBoundary(boundary)), nil
 829	case reflect.Uint8:
 830		return uint8(randomIntegerWithBoundary(boundary)), nil
 831	case reflect.Uint16:
 832		return uint16(randomIntegerWithBoundary(boundary)), nil
 833	case reflect.Uint32:
 834		return uint32(randomIntegerWithBoundary(boundary)), nil
 835	case reflect.Uint64:
 836		return uint64(randomIntegerWithBoundary(boundary)), nil
 837	case reflect.Int:
 838		return randomIntegerWithBoundary(boundary), nil
 839	case reflect.Int8:
 840		return int8(randomIntegerWithBoundary(boundary)), nil
 841	case reflect.Int16:
 842		return int16(randomIntegerWithBoundary(boundary)), nil
 843	case reflect.Int32:
 844		return int32(randomIntegerWithBoundary(boundary)), nil
 845	case reflect.Int64:
 846		return int64(randomIntegerWithBoundary(boundary)), nil
 847	default:
 848		return nil, errors.New(fakerErrors.ErrNotSupportedTypeForTag)
 849	}
 850}
 851
 852func getValueWithNoTag(t reflect.Type, opt options.Options) (interface{}, error) {
 853	switch t.Kind() {
 854	case reflect.Int, reflect.Int32, reflect.Int64, reflect.Int8, reflect.Int16, reflect.Uint, reflect.Uint8,
 855		reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:
 856		boundary := interfaces.RandomIntegerBoundary{
 857			Start: opt.RandomIntegerBoundary.Start,
 858			End:   opt.RandomIntegerBoundary.End}
 859		res, err := getNumberWithBoundary(t, boundary)
 860		if err != nil {
 861			return nil, err
 862		}
 863		return res, nil
 864	case reflect.String:
 865		res, err := randomString(opt.RandomStringLength, opt)
 866		if err != nil {
 867			return nil, err
 868		}
 869		return res, nil
 870	default:
 871		return 0, errors.New(fakerErrors.ErrUnknownType)
 872	}
 873}
 874
 875func userDefinedArray(v reflect.Value, tag string, opt options.Options) error {
 876	tagFunc, tagExists := mapperTag.Load(tag)
 877	if tagExists {
 878		res, err := tagFunc(v)
 879		if err != nil {
 880			return err
 881		}
 882		v.Set(reflect.ValueOf(res))
 883		return nil
 884	}
 885	sliceLen, err := extractSliceLengthFromTag(tag, opt)
 886	if err != nil {
 887		return err
 888	}
 889
 890	if opt.SetSliceMapNilIfLenZero && sliceLen == 0 {
 891		v.Set(reflect.Zero(v.Type()))
 892		return nil
 893	}
 894	//remove slice_len from tag string to avoid extra logic in downstream function
 895	tag = findSliceLenReg.ReplaceAllString(tag, "")
 896	array := reflect.MakeSlice(v.Type(), sliceLen, sliceLen)
 897	for i := 0; i < array.Len(); i++ {
 898		k := v.Type().Elem().Kind()
 899		if k == reflect.Pointer || k == reflect.Struct {
 900			res, err := getFakedValue(array.Index(i).Interface(), &opt)
 901			if err != nil {
 902				return err
 903			}
 904			if res.Kind() == reflect.Invalid {
 905				return fmt.Errorf("got invalid reflect value")
 906			}
 907			array.Index(i).Set(res)
 908			continue
 909		}
 910		if tag == "" {
 911			res, err := getValueWithNoTag(v.Type().Elem(), opt)
 912			if err != nil {
 913				return err
 914			}
 915			array.Index(i).Set(reflect.ValueOf(res))
 916			continue
 917		}
 918
 919		res, err := getValueWithTag(v.Type().Elem(), tag, opt)
 920		if err != nil {
 921			return err
 922		}
 923		array.Index(i).Set(reflect.ValueOf(res))
 924	}
 925	v.Set(array)
 926	return nil
 927}
 928
 929func userDefinedString(v reflect.Value, tag string, opt options.Options) error {
 930	var res interface{}
 931	var err error
 932
 933	if tagFunc, ok := mapperTag.Load(tag); ok {
 934		res, err = tagFunc(v)
 935		if err != nil {
 936			return err
 937		}
 938	} else {
 939		res, err = extractStringFromTag(tag, opt)
 940		if err != nil {
 941			return err
 942		}
 943	}
 944	if res == nil {
 945		return fmt.Errorf(fakerErrors.ErrTagNotSupported, tag)
 946	}
 947	val, _ := res.(string)
 948	v.SetString(val)
 949	return nil
 950}
 951
 952func userDefinedNumber(v reflect.Value, tag string) error {
 953	var res interface{}
 954	var err error
 955
 956	if tagFunc, ok := mapperTag.Load(tag); ok {
 957		res, err = tagFunc(v)
 958		if err != nil {
 959			return err
 960		}
 961	} else {
 962		res, err = extractNumberFromTag(tag, v.Type())
 963		if err != nil {
 964			return err
 965		}
 966	}
 967	if res == nil {
 968		return fmt.Errorf(fakerErrors.ErrTagNotSupported, tag)
 969	}
 970
 971	if v.CanSet() && v.CanConvert(v.Type()) {
 972		v.Set(reflect.ValueOf(res).Convert(v.Type()))
 973	}
 974	return nil
 975}
 976
 977// extractSliceLengthFromTag checks if the sliceLength tag 'slice_len' is set, if so, returns its value, else return a random length
 978func extractSliceLengthFromTag(tag string, opt options.Options) (int, error) {
 979	if strings.Contains(tag, SliceLength) {
 980		lenParts := strings.Split(findSliceLenReg.FindString(tag), Equals)
 981		if len(lenParts) != 2 {
 982			return 0, fmt.Errorf(fakerErrors.ErrWrongFormattedTag, tag)
 983		}
 984		sliceLen, err := strconv.Atoi(lenParts[1])
 985		if err != nil {
 986			return 0, fmt.Errorf("the given sliceLength has to be numeric, tag: %s", tag)
 987		}
 988		if sliceLen < 0 {
 989			return 0, fmt.Errorf("slice length can not be negative, tag: %s", tag)
 990		}
 991		return sliceLen, nil
 992	}
 993
 994	return randomSliceAndMapSize(opt), nil //Returns random slice length if the sliceLength tag isn't set
 995}
 996
 997func extractStringFromTag(tag string, opts options.Options) (interface{}, error) {
 998	var err error
 999	strlen := opts.RandomStringLength
1000	strlng := opts.StringLanguage
1001	isOneOfTag := strings.Contains(tag, ONEOF)
1002	if !strings.Contains(tag, Length) && !strings.Contains(tag, Language) && !isOneOfTag {
1003		return nil, fmt.Errorf(fakerErrors.ErrTagNotSupported, tag)
1004	}
1005	if strings.Contains(tag, Length) {
1006		lenParts := strings.Split(findLenReg.FindString(tag), Equals)
1007		if len(lenParts) != 2 {
1008			return nil, fmt.Errorf(fakerErrors.ErrWrongFormattedTag, tag)
1009		}
1010		strlen, _ = strconv.Atoi(lenParts[1])
1011	}
1012	if strings.Contains(tag, Language) {
1013		strlng, err = extractLangFromTag(tag)
1014		if err != nil {
1015			return nil, fmt.Errorf(fakerErrors.ErrWrongFormattedTag, tag)
1016		}
1017	}
1018	if isOneOfTag {
1019		var args []string
1020		args, err = fetchOneOfArgsFromTag(tag)
1021		if err != nil {
1022			return nil, err
1023		}
1024		toRet := args[rand.Intn(len(args))]
1025		return strings.TrimSpace(toRet), nil
1026	}
1027
1028	copyOption := opts
1029	copyOption.StringLanguage = strlng
1030	res, err := randomString(strlen, copyOption)
1031	return res, err
1032}
1033
1034func extractLangFromTag(tag string) (*interfaces.LangRuneBoundary, error) {
1035	text := findLangReg.FindString(tag)
1036	texts := strings.Split(text, Equals)
1037	if len(texts) != 2 {
1038		return nil, fmt.Errorf(fakerErrors.ErrWrongFormattedTag, text)
1039	}
1040	switch strings.ToLower(texts[1]) {
1041	case "eng":
1042		return &interfaces.LangENG, nil
1043	case "rus":
1044		return &interfaces.LangRUS, nil
1045	case "chi":
1046		return &interfaces.LangCHI, nil
1047	case "jpn":
1048		return &interfaces.LangJPN, nil
1049	case "kor":
1050		return &interfaces.LangKOR, nil
1051	case "emj":
1052		return &interfaces.EmotEMJ, nil
1053	default:
1054		return &interfaces.LangENG, nil
1055	}
1056}
1057
1058func extractNumberFromTag(tag string, t reflect.Type) (interface{}, error) {
1059	hasOneOf := strings.Contains(tag, ONEOF)
1060	hasBoundaryStart := strings.Contains(tag, BoundaryStart)
1061	hasBoundaryEnd := strings.Contains(tag, BoundaryEnd)
1062	usingOneOfTag := hasOneOf && (!hasBoundaryStart && !hasBoundaryEnd)
1063	usingBoundariesTags := !hasOneOf && (hasBoundaryStart && hasBoundaryEnd)
1064	if !usingOneOfTag && !usingBoundariesTags {
1065		return nil, fmt.Errorf(fakerErrors.ErrTagNotSupported, tag)
1066	}
1067
1068	// handling oneof tag
1069	if usingOneOfTag {
1070		args, err := fetchOneOfArgsFromTag(tag)
1071		if err != nil {
1072			return nil, err
1073		}
1074		switch t.Kind() {
1075		case reflect.Float64:
1076			{
1077				toRet, err := extractFloat64FromTagArgs(args)
1078				if err != nil {
1079					return nil, err
1080				}
1081				return toRet.(float64), nil
1082			}
1083		case reflect.Float32:
1084			{
1085				toRet, err := extractFloat32FromTagArgs(args)
1086				if err != nil {
1087					return nil, err
1088				}
1089				return toRet.(float32), nil
1090			}
1091		case reflect.Int64:
1092			{
1093				toRet, err := extractInt64FromTagArgs(args)
1094				if err != nil {
1095					return nil, err
1096				}
1097				return toRet.(int64), nil
1098			}
1099		case reflect.Int32:
1100			{
1101				toRet, err := extractInt32FromTagArgs(args)
1102				if err != nil {
1103					return nil, err
1104				}
1105				return toRet.(int32), nil
1106			}
1107		case reflect.Int16:
1108			{
1109				toRet, err := extractInt16FromTagArgs(args)
1110				if err != nil {
1111					return nil, err
1112				}
1113				return toRet.(int16), nil
1114			}
1115		case reflect.Int8:
1116			{
1117				toRet, err := extractInt8FromTagArgs(args)
1118				if err != nil {
1119					return nil, err
1120				}
1121				return toRet.(int8), nil
1122			}
1123		case reflect.Int:
1124			{
1125				toRet, err := extractIntFromTagArgs(args)
1126				if err != nil {
1127					return nil, err
1128				}
1129				return toRet.(int), nil
1130			}
1131		case reflect.Uint64:
1132			{
1133				toRet, err := extractUint64FromTagArgs(args)
1134				if err != nil {
1135					return nil, err
1136				}
1137				return toRet.(uint64), nil
1138			}
1139		case reflect.Uint32:
1140			{
1141				toRet, err := extractUint32FromTagArgs(args)
1142				if err != nil {
1143					return nil, err
1144				}
1145				return toRet.(uint32), nil
1146			}
1147		case reflect.Uint16:
1148			{
1149				toRet, err := extractUint16FromTagArgs(args)
1150				if err != nil {
1151					return nil, err
1152				}
1153				return toRet.(uint16), nil
1154			}
1155		case reflect.Uint8:
1156			{
1157				toRet, err := extractUint8FromTagArgs(args)
1158				if err != nil {
1159					return nil, err
1160				}
1161				return toRet.(uint8), nil
1162			}
1163		case reflect.Uint:
1164			{
1165				toRet, err := extractUintFromTagArgs(args)
1166				if err != nil {
1167					return nil, err
1168				}
1169				return toRet.(uint), nil
1170			}
1171		default:
1172			{
1173				return nil, fmt.Errorf("%s", fakerErrors.ErrUnsupportedNumberType)
1174			}
1175		}
1176	}
1177
1178	// handling boundary tags
1179	valuesStr := strings.Split(tag, comma)
1180	if len(valuesStr) != 2 {
1181		return nil, fmt.Errorf(fakerErrors.ErrWrongFormattedTag, tag)
1182	}
1183
1184	// TODO(Xaspy): When Golang provides generics, we will be able to make this method simpler and more beautiful.
1185	if t.Kind() == reflect.Float64 || t.Kind() == reflect.Float32 {
1186		startBoundary, err := extractFloatFromText(valuesStr[0])
1187		if err != nil {
1188			return nil, err
1189		}
1190		endBoundary, err := extractFloatFromText(valuesStr[1])
1191		if err != nil {
1192			return nil, err
1193		}
1194		boundary := interfaces.RandomFloatBoundary{Start: startBoundary, End: endBoundary}
1195		switch t.Kind() {
1196		case reflect.Float32:
1197			return float32(randomFloatWithBoundary(boundary)), nil
1198		case reflect.Float64:
1199			return randomFloatWithBoundary(boundary), nil
1200		}
1201	}
1202
1203	startBoundary, err := extractIntFromText(valuesStr[0])
1204	if err != nil {
1205		return nil, err
1206	}
1207	endBoundary, err := extractIntFromText(valuesStr[1])
1208	if err != nil {
1209		return nil, err
1210	}
1211	boundary := interfaces.RandomIntegerBoundary{Start: startBoundary, End: endBoundary}
1212	return getNumberWithBoundary(t, boundary)
1213}
1214
1215func extractIntFromText(text string) (int, error) {
1216	text = strings.TrimSpace(text)
1217	texts := strings.Split(text, Equals)
1218	if len(texts) != 2 {
1219		return 0, fmt.Errorf(fakerErrors.ErrWrongFormattedTag, text)
1220	}
1221	return strconv.Atoi(texts[1])
1222}
1223
1224func extractFloatFromText(text string) (float64, error) {
1225	text = strings.TrimSpace(text)
1226	texts := strings.Split(text, Equals)
1227	if len(texts) != 2 {
1228		return 0, fmt.Errorf(fakerErrors.ErrWrongFormattedTag, text)
1229	}
1230	return strconv.ParseFloat(texts[1], 64)
1231}
1232
1233func fetchOneOfArgsFromTag(tag string) ([]string, error) {
1234	items := strings.Split(tag, colon)
1235	argsList := items[1:]
1236	if len(argsList) != 1 {
1237		return nil, fmt.Errorf("%s", fakerErrors.ErrUnsupportedTagArguments)
1238	}
1239	if strings.Contains(argsList[0], ",,") {
1240		return nil, fmt.Errorf("%s", fakerErrors.ErrDuplicateSeparator)
1241	}
1242	if argsList[0] == "" {
1243		return nil, fmt.Errorf("%s", fakerErrors.ErrNotEnoughTagArguments)
1244	}
1245	args := strings.Split(argsList[0], comma)
1246	if len(args) < 1 {
1247		return nil, fmt.Errorf("%s", fakerErrors.ErrNotEnoughTagArguments)
1248	}
1249	return args, nil
1250}
1251
1252func randomString(n int, fakerOpt options.Options) (string, error) {
1253	b := make([]rune, 0)
1254	set := make(map[rune]struct{})
1255	if fakerOpt.StringLanguage.Exclude != nil {
1256		for _, s := range fakerOpt.StringLanguage.Exclude {
1257			set[s] = struct{}{}
1258		}
1259	}
1260
1261	counter := 0
1262	for i := 0; i < n; {
1263		randRune := rune(rand.Intn(int(fakerOpt.StringLanguage.End-fakerOpt.StringLanguage.Start)) + int(fakerOpt.StringLanguage.Start))
1264		for slice.ContainsRune(set, randRune) {
1265			if counter++; counter >= fakerOpt.MaxGenerateStringRetries {
1266				return "", errors.New("max number of string generation retries exhausted")
1267			}
1268			randRune = rune(rand.Intn(int(fakerOpt.StringLanguage.End-fakerOpt.StringLanguage.Start)) + int(fakerOpt.StringLanguage.Start))
1269			_, ok := set[randRune]
1270			if !ok {
1271				break
1272			}
1273		}
1274		b = append(b, randRune)
1275		i++
1276	}
1277
1278	k := string(b)
1279	return k, nil
1280}
1281
1282// randomIntegerWithBoundary returns a random integer between input start and end boundary. [start, end)
1283func randomIntegerWithBoundary(boundary interfaces.RandomIntegerBoundary) int {
1284	span := boundary.End - boundary.Start
1285	if span <= 0 {
1286		return boundary.Start
1287	}
1288	return rand.Intn(span) + boundary.Start
1289}
1290
1291// randomFloatWithBoundary returns a random float between input start and end boundary. [start, end)
1292func randomFloatWithBoundary(boundary interfaces.RandomFloatBoundary) float64 {
1293	span := boundary.End - boundary.Start
1294	if span <= 0 {
1295		return boundary.Start
1296	}
1297	return boundary.Start + rand.Float64()*span
1298}
1299
1300// randomInteger returns a random integer between start and end boundary. [start, end)
1301func randomInteger(opt *options.Options) int {
1302	if opt == nil {
1303		opt = options.DefaultOption()
1304	}
1305
1306	return randomIntegerWithBoundary(*opt.RandomIntegerBoundary)
1307}
1308
1309// randomFloat returns a random float between start and end boundary. [start, end)
1310func randomFloat(opt *options.Options) float64 {
1311	if opt == nil {
1312		opt = options.DefaultOption()
1313	}
1314
1315	return randomFloatWithBoundary(*opt.RandomFloatBoundary)
1316}
1317
1318// randomSliceAndMapSize returns a random integer between [0,randomSliceAndMapSize). If the testRandZero is set, returns 0
1319// Written for test purposes for shouldSetNil
1320func randomSliceAndMapSize(opt options.Options) int {
1321	if opt.SetSliceMapRandomToZero {
1322		return 0
1323	}
1324	r := opt.RandomMaxSliceSize - opt.RandomMinSliceSize
1325	if r < 1 {
1326		r = 1
1327	}
1328	return opt.RandomMinSliceSize + rand.Intn(r)
1329}
1330
1331func randomElementFromSliceString(s []string) string {
1332	return s[rand.Int()%len(s)]
1333}
1334func randomStringNumber(n int) string {
1335	b := make([]byte, n)
1336	for i, cache, remain := n-1, rand.Int63(), letterIdxMax; i >= 0; {
1337		if remain == 0 {
1338			cache, remain = rand.Int63(), letterIdxMax
1339		}
1340		if idx := int(cache & letterIdxMask); idx < len(numberBytes) {
1341			b[i] = numberBytes[idx]
1342			i--
1343		}
1344		cache >>= letterIdxBits
1345		remain--
1346	}
1347
1348	return string(b)
1349}
1350
1351// RandomInt Get three parameters , only first mandatory and the rest are optional
1352// (minimum_int, maximum_int, count)
1353//
1354//	If only set one parameter :  An integer greater than minimum_int will be returned
1355//	If only set two parameters : All integers between minimum_int and maximum_int will be returned, in a random order.
1356//	If three parameters: `count` integers between minimum_int and maximum_int will be returned.
1357func RandomInt(parameters ...int) (p []int, err error) {
1358	switch len(parameters) {
1359	case 1:
1360		minInt := parameters[0]
1361		p = rand.Perm(minInt)
1362		for i := range p {
1363			p[i] += minInt
1364		}
1365	case 2:
1366		minInt, maxInt := parameters[0], parameters[1]
1367		p = rand.Perm(maxInt - minInt + 1)
1368
1369		for i := range p {
1370			p[i] += minInt
1371		}
1372	case 3:
1373		minInt, maxInt := parameters[0], parameters[1]
1374		count := parameters[2]
1375		p = rand.Perm(maxInt - minInt + 1)
1376
1377		for i := range p {
1378			p[i] += minInt
1379		}
1380		if len(p) > count {
1381			p = p[0:count]
1382		}
1383	default:
1384		err = fmt.Errorf(fakerErrors.ErrMoreArguments, len(parameters))
1385	}
1386	return p, err
1387}
1388
1389func generateUnique(dataType string, fn func() interface{}) (interface{}, error) {
1390	for i := 0; i < maxRetry; i++ {
1391		value := fn()
1392		uniqueVal, _ := uniqueValues.Load(dataType)
1393		uniqueValArr, _ := uniqueVal.([]interface{})
1394		if !slice.ContainsValue(uniqueValArr, value) { // Retry if unique value already found
1395			uniqueValues.Store(dataType, append(uniqueValArr, value))
1396			return value, nil
1397		}
1398	}
1399	return reflect.Value{}, fmt.Errorf(fakerErrors.ErrUniqueFailure, dataType)
1400}
1401
1402func singleFakeData(dataType string, fn func() interface{}, opts ...options.OptionFunc) interface{} {
1403	ops := initOption(opts...)
1404	if ops.GenerateUniqueValues {
1405		v, err := generateUnique(dataType, fn)
1406		if err != nil {
1407			panic(err)
1408		}
1409		return v
1410	}
1411	return fn()
1412}