@@ -161,21 +161,37 @@ func NewStringGenerator() *StringGenerator {
161161func (g * StringGenerator ) Generate (params map [string ]any , column * ColumnInfo ) (any , error ) {
162162 length := getParam (params , "length" , 10 )
163163 charset := getParam (params , "charset" , defaultCharset )
164+ unique := getParam (params , "unique" , false )
165+ index := getParam (params , "_index" , - 1 )
164166
165167 if length <= 0 {
166168 return nil , fmt .Errorf ("length must be positive" )
167169 }
168170
169- // Apply column max length constraint if available
170171 if column .MaxLength != nil && length > * column .MaxLength {
171172 length = * column .MaxLength
172173 }
173174
175+ // Deterministic unique string based on index
176+ if unique && index >= 0 {
177+ base := fmt .Sprintf ("%d" , index )
178+ if len (base ) > length {
179+ return nil , fmt .Errorf ("unique string generator: index %d requires %d chars but length is %d" , index , len (base ), length )
180+ }
181+ if len (base ) == length {
182+ return base , nil
183+ }
184+ padding := make ([]byte , length - len (base ))
185+ for i := range padding {
186+ padding [i ] = charset [(index + i )% len (charset )]
187+ }
188+ return string (padding ) + base , nil
189+ }
190+
174191 result := make ([]byte , length )
175192 for i := range result {
176193 result [i ] = charset [rand .Intn (len (charset ))]
177194 }
178-
179195 return string (result ), nil
180196}
181197
@@ -227,16 +243,20 @@ func NewEmailGenerator() *EmailGenerator {
227243
228244func (g * EmailGenerator ) Generate (params map [string ]any , column * ColumnInfo ) (any , error ) {
229245 domain := getParam (params , "domain" , "" )
230-
231- prefix := emailPrefixes [rand .Intn (len (emailPrefixes ))]
232- suffix := rand .Intn (10000 )
246+ index := getParam (params , "_index" , - 1 )
233247
234248 if domain == "" {
235249 domain = emailDomains [rand .Intn (len (emailDomains ))]
236250 }
237251
238- email := fmt .Sprintf ("%s%d@%s" , prefix , suffix , domain )
239- return email , nil
252+ // Use index for guaranteed uniqueness when available
253+ if index >= 0 {
254+ return fmt .Sprintf ("user%d@%s" , index , domain ), nil
255+ }
256+
257+ prefix := emailPrefixes [rand .Intn (len (emailPrefixes ))]
258+ suffix := rand .Intn (10000 )
259+ return fmt .Sprintf ("%s%d@%s" , prefix , suffix , domain ), nil
240260}
241261
242262func (g * EmailGenerator ) Validate (params map [string ]any , column * ColumnInfo ) error {
@@ -251,20 +271,42 @@ func NewNameGenerator() *NameGenerator {
251271
252272func (g * NameGenerator ) Generate (params map [string ]any , column * ColumnInfo ) (any , error ) {
253273 nameType := getParam (params , "type" , "full" )
254-
255- firstName := firstNames [rand .Intn (len (firstNames ))]
256- lastName := lastNames [rand .Intn (len (lastNames ))]
257-
274+ unique := getParam (params , "unique" , false )
275+ index := getParam (params , "_index" , - 1 )
276+
277+ var firstName , lastName string
278+ if unique && index >= 0 {
279+ firstName = firstNames [index % len (firstNames )]
280+ lastName = lastNames [index % len (lastNames )]
281+ // Add suffix when names would cycle
282+ cycle := index / (len (firstNames ) * len (lastNames ))
283+ if cycle > 0 {
284+ lastName = fmt .Sprintf ("%s%d" , lastName , cycle )
285+ }
286+ } else {
287+ firstName = firstNames [rand .Intn (len (firstNames ))]
288+ lastName = lastNames [rand .Intn (len (lastNames ))]
289+ }
290+
291+ var result string
258292 switch nameType {
259293 case "first" :
260- return firstName , nil
294+ result = firstName
261295 case "last" :
262- return lastName , nil
296+ result = lastName
263297 case "full" :
264- return fmt .Sprintf ("%s %s" , firstName , lastName ), nil
298+ result = fmt .Sprintf ("%s %s" , firstName , lastName )
265299 default :
266300 return nil , fmt .Errorf ("unsupported name type: %s" , nameType )
267301 }
302+
303+ if column .MaxLength != nil && len (result ) > * column .MaxLength {
304+ if unique {
305+ return nil , fmt .Errorf ("unique name generator: result %q (%d chars) exceeds column max length %d" , result , len (result ), * column .MaxLength )
306+ }
307+ result = result [:* column .MaxLength ]
308+ }
309+ return result , nil
268310}
269311
270312func (g * NameGenerator ) Validate (params map [string ]any , column * ColumnInfo ) error {
0 commit comments