/
generator.go
179 lines (153 loc) · 4.61 KB
/
generator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright (c) 2023 0x6flab
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
// http://www.apache.org/licenses/LICENSE-2.0
package namegenerator
import (
"crypto/rand"
"math/big"
mrand "math/rand"
"time"
)
func init() {
mrand.New(mrand.NewSource(time.Now().UnixNano()))
}
type Gender uint8
const (
Male Gender = iota
Female
NonBinary
)
// NameGenerator is an interface for generating names.
type NameGenerator interface {
// Generate generates a name based on the gender.
//
// Example:
// generator := namegenerator.NewGenerator()
// name := generator.Generate()
// fmt.Println(name)
// Output:
// `John-Smith`
Generate() string
// GenerateMultiple generates a list of names.
//
// Example:
// generator := namegenerator.NewGenerator()
// names := generator.GenerateMultiple(10)
// fmt.Println(names)
// Output:
// `[Dryke-Monroe Scarface-Lesway Shelden-Corsale Marcus-Ivett Victor-Nesrallah Merril-Gulick Leonardo-Lindler Maurits-Lias Rawley-Connor Elvis-Khouderchah]`
GenerateMultiple(count int) []string
// WithGender generates a name based on the gender.
//
// Example:
// generator := namegenerator.NewGenerator().WithGender(namegenerator.Male)
// name := generator.Generate()
// fmt.Println(name)
// Output:
// `John-Smith`
WithGender(gender Gender) NameGenerator
// WithPrefix generates a name with a prefix.
//
// Example:
// generator := namegenerator.NewGenerator().WithPrefix("Mr. ")
// name := generator.Generate()
// fmt.Println(name)
// Output:
// `Mr. John-Smith`
WithPrefix(prefix string) NameGenerator
// WithSuffix generates a name with a suffix.
//
// Example:
// generator := namegenerator.NewGenerator().WithSuffix("@gmail.com")
// name := generator.Generate()
// fmt.Println(name)
// Output:
// `John-Smith@gmail.com`
WithSuffix(suffix string) NameGenerator
}
// nameGenerator is a struct that implements NameGenerator.
type nameGenerator struct {
gender Gender
prefix string
suffix string
}
// NewGenerator returns a new NameGenerator.
//
// Example to generate general names:
//
// generator := namegenerator.NewGenerator()
//
// Example to generate male names:
//
// generator := namegenerator.NewGenerator().WithGender(namegenerator.Male)
//
// Example to generate female names:
//
// generator := namegenerator.NewGenerator().WithGender(namegenerator.Female)
//
// Example to generate non-binary names:
//
// generator := namegenerator.NewGenerator().WithGender(namegenerator.NonBinary)
//
// Example to generate names with a prefix:
//
// generator := namegenerator.NewGenerator().WithPrefix("Mr. ")
//
// Example to generate names with a suffix:
//
// generator := namegenerator.NewGenerator().WithSuffix("@gmail.com")
func NewGenerator() NameGenerator {
return &nameGenerator{
gender: NonBinary,
}
}
func (namegen *nameGenerator) WithGender(gender Gender) NameGenerator {
namegen.gender = gender
return namegen
}
func (namegen *nameGenerator) WithPrefix(prefix string) NameGenerator {
namegen.prefix = prefix
return namegen
}
func (namegen *nameGenerator) WithSuffix(suffix string) NameGenerator {
namegen.suffix = suffix
return namegen
}
func (namegen *nameGenerator) Generate() string {
switch namegen.gender {
case Male:
grandom := namegen.generateRandomNumber(len(MaleNames))
frandom := namegen.generateRandomNumber(len(FamilyNames))
return namegen.prefix + MaleNames[grandom] + "-" + FamilyNames[frandom] + namegen.suffix
case Female:
grandom := namegen.generateRandomNumber(len(FemaleNames))
frandom := namegen.generateRandomNumber(len(FamilyNames))
return namegen.prefix + FemaleNames[grandom] + "-" + FamilyNames[frandom] + namegen.suffix
case NonBinary:
fallthrough
// This condition never happens, but it's here to make the compiler happy.
default:
g1random := namegen.generateRandomNumber(len(GeneralNames))
g2random := namegen.generateRandomNumber(len(GeneralNames))
return namegen.prefix + GeneralNames[g1random] + "-" + GeneralNames[g2random] + namegen.suffix
}
}
func (namegen *nameGenerator) GenerateMultiple(count int) []string {
names := make([]string, count)
for i := 0; i < count; i++ {
names[i] = namegen.Generate()
}
return names
}
// generateRandomNumber generates a random number.
// If the random number generator fails, it will use the math/rand package.
func (namegen *nameGenerator) generateRandomNumber(max int) uint64 {
random, err := rand.Int(rand.Reader, big.NewInt(int64(max)))
if err != nil {
random = big.NewInt(mrand.Int63n(int64(max)))
}
return random.Uint64()
}