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}