Skip to content

Commit

Permalink
Genesis
Browse files Browse the repository at this point in the history
  • Loading branch information
Bios-Marcel committed Nov 3, 2023
0 parents commit 34b0e34
Show file tree
Hide file tree
Showing 10 changed files with 465 additions and 0 deletions.
29 changes: 29 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
BSD 3-Clause License

Copyright (c) 2019, scribble-rs
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## Alternative to dustinkirklands golang-petname.

[![Verify](https://github.com/Bios-Marcel/go-petname/actions/workflows/go.yml/badge.svg)](https://github.com/Bios-Marcel/go-petname/actions/workflows/go.yml)
[![Go Reference](https://pkg.go.dev/badge/github.com/Bios-Marcel/go-petname.svg)](https://pkg.go.dev/github.com/Bios-Marcel/go-petname)

**!The API is incompatible with dustinkirkland/golang-petname!**

The goal is to provide a low overhead alternative that'S well-maintained and
simple to work with.

## Usage

Add to your dependencies:

```sh
go get github.com/Bios-Marcel/go-petname
```

Call the `Generate` function:

```go
petname.Generate(3, petname.Lower, petname.Underscore)
```

You can change the wordlists by calling `SetNames`, `SetAdjectives` and
`SetAdverbs`. Note that by default, the `short` package is used as the source of
words for all groups. The other packages available are `medium` and `long`.

Technically you can provide your own lists.

## Generate wordlists

The wordlists are generated like this:

```sh
go run ./cmd/generate folder > target/words.go
```

Replace `folder` with the folder that contains `adjectives.txt`, `adverbs.txt`
and `names.txt`.

46 changes: 46 additions & 0 deletions cmd/generate/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"
)

func main() {
path := os.Args[1]

fmt.Printf(
`package %s
var (
Adjectives = []string{%s}
Adverbs = []string{%s}
Names = []string{%s}
)
// vim: nowrap`,
filepath.Base(path),
toCommaSeparatedStringLiterals(filepath.Join(path, "adjectives.txt")),
toCommaSeparatedStringLiterals(filepath.Join(path, "adverbs.txt")),
toCommaSeparatedStringLiterals(filepath.Join(path, "names.txt")))
}

func toCommaSeparatedStringLiterals(path string) string {
f, err := os.Open(path)
if err != nil {
panic(err)
}
defer f.Close()

scan := bufio.NewScanner(f)
var list strings.Builder
for scan.Scan() {
list.WriteRune('"')
list.WriteString(scan.Text())
list.WriteString(`", `)
}

return list.String()
}
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module github.com/Bios-Marcel/go-petname

go 1.21.3

require github.com/stretchr/testify v1.8.4

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
9 changes: 9 additions & 0 deletions long/words.go

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions medium/words.go

Large diffs are not rendered by default.

171 changes: 171 additions & 0 deletions petname.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// Package petname is a library for generating human-readable, random
// names for objects (e.g. hostnames, containers, blobs).
package petname

import (
"math/rand"
"time"

"github.com/Bios-Marcel/go-petname/short"
)

var names, adjectives, adverbs []string

func init() {
SetNames(short.Names)
SetAdjectives(short.Adjectives)
SetAdverbs(short.Adverbs)
}

// SetNames specifies which names to use when generating petnames. Note that
// these are expected to be all lowercase characters and not containing any
// trailing or leading whitespace.
func SetNames(n []string) {
names = n
}

// SetAdjectives specifies which adjectives to use when generating petnames.
// Note that these are expected to be all lowercase characters and not
// containing any trailing or leading whitespace.
func SetAdjectives(a []string) {
adjectives = a
}

// SetAdverbs specifies which adverbs to use when generating petnames. Note
// that these are expected to be all lowercase characters and not containing
// any trailing or leading whitespace.
func SetAdverbs(a []string) {
adverbs = a
}

var localRand *rand.Rand = rand.New(rand.NewSource(1))

// NonDeterministicMode configures the local random generator used internally
// to provide non deterministic results, instead of a pre-defined order that is
// reproducible even after a process restart. If you wish to specify a custom
// contant, call [Seed(int64)].
func NonDeterministicMode() {
localRand.Seed(time.Now().UnixNano())
}

// Seed configures the local random generator, allowing you to specify a
// constant for reproducible "randomness" or provide a custom value for
// "true" randomness.
func Seed(seed int64) {
localRand.Seed(seed)
}

// Adverb returns a random adverb from a list of petname adverbs.
func Adverb() string {
return adverbs[localRand.Intn(len(adverbs))]
}

// Adjective returns a random adjective from a list of petname adjectives.
func Adjective() string {
return adjectives[localRand.Intn(len(adjectives))]
}

// Name returns a random name from a list of petname names.
func Name() string {
return names[localRand.Intn(len(names))]
}

// Casing specifies the casing of the overall petname, not its separate words.
type Casing int

const (
// Lower will keep all letters as they are. Since the requirement for the
// word lists is that they are all lowercase, this will result in a NO-OP.
Lower Casing = iota
// Upper will uppercase all letters.
Upper
// Title will uppercase the first letter and keep the rest lowercased..
Title
)

// Separator specifies the separator between words in a petname.
type Separator = byte

const (
None Separator = 0
Hyphen Separator = '-'
Underscore Separator = '_'
)

func asciiByteToUpper(b byte) byte {
if b >= 'a' && b <= 'z' {
return b - 32
}

return b
}

// Generate will create a petname using the given configuration. Casing and
// word separation are different, allowing things such as `Word-Word-Word` or
// `WORD_WORD_WORD`.
func Generate(wordCount uint, casing Casing, separator Separator) string {
var words []string
switch wordCount {
case 0:
// Without this case, passing 0 as the wordCount will cause a very
// slow call. This is because we are using a unit, which we'll subtract
// 2 from, causing MaxUint - 2 iterations.
return ""
case 1:
words = []string{Name()}
case 2:
words = []string{Adjective(), Name()}
case 3:
// Potentially common cases have shortcut implementations to
// reduce allocations and CPU usage, even though default: would handle
// them correctly.
words = []string{Adverb(), Adjective(), Name()}
case 4:
words = []string{Adverb(), Adverb(), Adjective(), Name()}
default:
words = make([]string, 0, wordCount)
for i := uint(0); i < wordCount-2; i++ {
words = append(words, Adverb())
}

words = append(words, Adjective(), Name())
}

var byteLen int
for _, word := range words {
byteLen += len(word)
}

if separator != None {
byteLen += len(words) - 1
}

var buffer []byte
if byteLen <= 64 {
buffer = make([]byte, 0, 64)
} else {
buffer = make([]byte, 0, byteLen)
}

for _, word := range words {
if separator != None && len(buffer) > 0 {
buffer = append(buffer, separator)
}

switch casing {
case Upper:
for i := 0; i < len(word); i++ {
buffer = append(buffer, asciiByteToUpper(word[i]))
}
case Title:
buffer = append(buffer, asciiByteToUpper(word[0]))
buffer = append(buffer, word[1:]...)
case Lower:
fallthrough
default:
buffer = append(buffer, word...)
}
}

return string(buffer)
}
Loading

0 comments on commit 34b0e34

Please sign in to comment.