Compare commits

..

No commits in common. "10eb3f2491df7b80d62ff17871d8ca8d83a1408d" and "72791d4fac41f02a8aa6cc3a8af41d2e3f8787c8" have entirely different histories.

19 changed files with 462 additions and 675 deletions

View file

@ -1,19 +1,5 @@
# Changelog
### [0.3.0] - 2025-03-14
#### Features
- Simplified multiple Generator functions to single function with options
- Added a lot of examples for docs
- Can add extra Options to Make
Multiple breaking changes around Generators.
#### Bugs
- Fixed date formats
### [0.2.1] - 2025-03-14
#### Features

View file

@ -4,8 +4,6 @@ The purpose of nomino is to generate (probably random) filenames, for example, i
It takes a lot of inspiration (although no actual code) from [Onym](https://github.com/Blaspsoft/onym).
Note that this is still not at a stable release. There will be breaking changes between minor releases until it reaches 1.0.0. Patch releases shouldn't contain breaking changes however. Once it reaches 1.0.0, breaking changes will only happen between major releases.
## TODO
I'll fill this out more in depth later.

View file

@ -1,81 +0,0 @@
package nomino
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"errors"
"fmt"
"hash"
"github.com/gosimple/slug"
)
// ErrMissingOriginal is the error returned by Slug if there is no filename
var ErrMissingOriginal = errors.New("missing original filename")
func getOriginal(c *Config) (string, error) {
if c.original == "" {
return "", ErrMissingOriginal
}
name := c.original
c.original = ""
return name, nil
}
// Slug generates a name from the original filename.
// When this is used, the original filename will be removed from the final filename.
// If a language is specified, that may affect the resulting slug.
func Slug(lang ...string) Generator {
ret := slug.Make
if len(lang) > 0 {
ret = func(in string) string {
return slug.MakeLang(in, lang[0])
}
}
return func(c *Config) (string, error) {
name, err := getOriginal(c)
return ret(name), err
}
}
// HashingFunc is a function that generates a hash.Hash
type HashingFunc func() hash.Hash
//go:generate stringer -type=HashType -trimprefix=Hash
// HashType represents a particular hashing algorithm
type HashType uint8
const (
HashMD5 HashType = iota + 1
HashSHA1
HashSHA256
)
// ErrInvalidHashType is returned by the Hash generator when an invalid HashType is passed
var ErrInvalidHashType = errors.New("invalid hash type")
var hashMap = map[HashType]HashingFunc{
HashMD5: md5.New,
HashSHA1: sha1.New,
HashSHA256: sha256.New,
}
// Hash generates a name from a hash of the filename.
// When this is used, the original filename will be removed from the final filename.
func Hash(t HashType) Generator {
f, ok := hashMap[t]
return func(c *Config) (string, error) {
if !ok {
return "", fmt.Errorf("%w: %s", ErrInvalidHashType, t)
}
name, err := getOriginal(c)
if err != nil {
return "", err
}
hs := f()
hs.Write([]byte(name))
return fmt.Sprintf("%x", hs.Sum(nil)), nil
}
}

View file

@ -1,66 +0,0 @@
package nomino_test
import (
"fmt"
"codeberg.org/danjones000/nomino"
)
func ExampleSlug() {
conf := nomino.NewConfig(
nomino.WithOriginal("My name is Jimmy"),
nomino.WithGenerator(nomino.Slug()),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
// Output: my-name-is-jimmy.txt
}
func ExampleSlug_withLang() {
conf := nomino.NewConfig(
nomino.WithOriginal("Diese & Dass"),
nomino.WithGenerator(nomino.Slug("de")),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
// Output: diese-und-dass.txt
}
func ExampleHash_mD5() {
conf := nomino.NewConfig(
nomino.WithOriginal("foobar"),
nomino.WithGenerator(
nomino.Hash(nomino.HashMD5),
),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
// Output: 3858f62230ac3c915f300c664312c63f.txt
}
func ExampleHash_sHA1() {
conf := nomino.NewConfig(
nomino.WithOriginal("foobar"),
nomino.WithGenerator(
nomino.Hash(nomino.HashSHA1),
),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
// Output: 8843d7f92416211de9ebb963ff4ce28125932878.txt
}
func ExampleHash_sHA256() {
conf := nomino.NewConfig(
nomino.WithOriginal("foobar"),
nomino.WithGenerator(
nomino.Hash(nomino.HashSHA256),
),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
// Output: c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2.txt
}

View file

@ -1,42 +0,0 @@
package nomino
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSlugMissingFilename(t *testing.T) {
conf := NewConfig(WithGenerator(Slug()))
st, err := conf.generator(&conf)
assert.Zero(t, st)
assert.ErrorIs(t, err, ErrMissingOriginal)
}
func TestSlugRemovesOriginal(t *testing.T) {
conf := NewConfig(WithGenerator(Slug()), WithOriginal("Hello, World"))
st, err := conf.generator(&conf)
assert.Zero(t, conf.original)
assert.Equal(t, "hello-world", st)
assert.NoError(t, err)
}
func TestHashBadHash(t *testing.T) {
conf := NewConfig(WithOriginal("foobar"), WithGenerator(Hash(0)))
st, err := conf.generator(&conf)
assert.Equal(t, "", st)
assert.ErrorIs(t, err, ErrInvalidHashType)
assert.ErrorContains(t, err, "invalid hash type: HashType(0)")
}
func TestHashMissingOriginal(t *testing.T) {
conf := NewConfig(WithGenerator(Hash(HashMD5)))
st, err := conf.generator(&conf)
assert.Equal(t, "", st)
assert.ErrorIs(t, err, ErrMissingOriginal)
}
func TestHashTypeStringer(t *testing.T) {
s := HashMD5.String()
assert.Equal(t, "MD5", s)
}

View file

@ -1,55 +0,0 @@
package nomino
import (
"fmt"
"strconv"
)
type incConf struct {
start int
step int
cb func(int) string
}
// IncrementalOption sets an option for the Incremental Generator
type IncrementalOption func(c *incConf)
// Incremental generates a name that is a series of integers.
// By default it begins at 0 and increments by 1 each time.
func Incremental(opts ...IncrementalOption) Generator {
c := incConf{step: 1, cb: strconv.Itoa}
for _, opt := range opts {
opt(&c)
}
next := c.start
return func(*Config) (string, error) {
out := c.cb(next)
next += c.step
return out, nil
}
}
// IncrementalStart sets the starting integer for Incremental
func IncrementalStart(start int) IncrementalOption {
return func(c *incConf) {
c.start = start
}
}
// IncrementalStepsets the step by which Incremental increases with each invocation.
func IncrementalStep(step int) IncrementalOption {
return func(c *incConf) {
c.step = step
}
}
// IncrementalFormatsets the format for the number generated by Incremental.
// It will be formatted with Printf. This is mostly likely useful with a format like "%02d"
func IncrementalFormat(format string) IncrementalOption {
return func(c *incConf) {
c.cb = func(i int) string {
return fmt.Sprintf(format, i)
}
}
}

View file

@ -1,121 +0,0 @@
package nomino_test
import (
"fmt"
"codeberg.org/danjones000/nomino"
)
func ExampleIncremental() {
conf := nomino.NewConfig(
nomino.WithPrefix("foo"),
nomino.WithGenerator(nomino.Incremental()),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
// Output:
// foo_0.txt
// foo_1.txt
// foo_2.txt
}
func ExampleIncrementalStart() {
conf := nomino.NewConfig(
nomino.WithPrefix("foo"),
nomino.WithGenerator(nomino.Incremental(
nomino.IncrementalStart(42),
)),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
// Output:
// foo_42.txt
// foo_43.txt
// foo_44.txt
}
func ExampleIncrementalStep() {
conf := nomino.NewConfig(
nomino.WithPrefix("foo"),
nomino.WithGenerator(nomino.Incremental(
nomino.IncrementalStep(2),
)),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
// Output:
// foo_0.txt
// foo_2.txt
// foo_4.txt
}
func ExampleIncremental_withStartAndStep() {
conf := nomino.NewConfig(
nomino.WithPrefix("foo"),
nomino.WithGenerator(nomino.Incremental(
nomino.IncrementalStart(42),
nomino.IncrementalStep(2),
)),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
// Output:
// foo_42.txt
// foo_44.txt
// foo_46.txt
}
func ExampleIncrementalFormat() {
conf := nomino.NewConfig(
nomino.WithPrefix("foo"),
nomino.WithGenerator(nomino.Incremental(
nomino.IncrementalFormat("%03d"),
)),
)
str, _ := nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
str, _ = nomino.Make(conf)
fmt.Println(str)
// Output:
// foo_000.txt
// foo_001.txt
// foo_002.txt
}

View file

@ -1,59 +0,0 @@
package nomino
import "time"
// FileTimestamp is the default format for WithTimestamp and WithTime
const FileTimestamp string = "2006-01-02T15-04-05-0700"
// FileTimestampNoTZ is the default format for WithTimestampUTC and WithTimeUTC
const FileTimestampNoTZ string = "2006-01-02T15-04-05"
type timestampConf struct {
format string
ts time.Time
utc bool
}
// TimestampOption provides options for the Timestamp Generator
type TimestampOption func(c *timestampConf)
// Timestamp generates a a date and time. By default, it uses the current time, and will.
// be formatted accourding to FileTimestamp
func Timestamp(opts ...TimestampOption) Generator {
c := timestampConf{format: FileTimestamp, ts: time.Now()}
for _, opt := range opts {
opt(&c)
}
if c.utc {
c.ts = c.ts.UTC()
}
return func(*Config) (string, error) {
return c.ts.Format(c.format), nil
}
}
// TimestampFormat sets the format for the generated name.
// Consult time.Time.Format for details on the format.
func TimestampFormat(format string) TimestampOption {
return func(c *timestampConf) {
c.format = format
}
}
// TimestampTime sets the time for the generated name.
// By default, it uses the current time.
func TimestampTime(t time.Time) TimestampOption {
return func(c *timestampConf) {
c.ts = t
}
}
// TimestampUTC uses the time in UTC, while also stripping the timezone from the format.
func TimestampUTC() TimestampOption {
return func(c *timestampConf) {
c.utc = true
c.format = FileTimestampNoTZ
}
}

View file

@ -1,45 +0,0 @@
package nomino_test
import (
"fmt"
"time"
"codeberg.org/danjones000/nomino"
)
func ExampleTimestamp() {
gen := nomino.Timestamp()
conf := nomino.NewConfig(nomino.WithGenerator(gen))
s, _ := nomino.Make(conf)
fmt.Println(s)
}
func ExampleTimestampTime() {
tz, _ := time.LoadLocation("America/New_York")
ts := time.Date(2009, time.January, 20, 12, 5, 0, 0, tz)
gen := nomino.Timestamp(nomino.TimestampTime(ts))
conf := nomino.NewConfig(nomino.WithGenerator(gen))
s, _ := nomino.Make(conf)
fmt.Println(s)
// Output: 2009-01-20T12-05-00-0500.txt
}
func ExampleTimestampFormat() {
tz, _ := time.LoadLocation("America/New_York")
ts := time.Date(2009, time.January, 20, 12, 5, 0, 0, tz)
gen := nomino.Timestamp(nomino.TimestampTime(ts), nomino.TimestampFormat("2006#01#02<>15|04|05-0700"))
conf := nomino.NewConfig(nomino.WithGenerator(gen))
s, _ := nomino.Make(conf)
fmt.Println(s)
// Output: 2009#01#20<>12|05|00-0500.txt
}
func ExampleTimestampUTC() {
tz, _ := time.LoadLocation("America/New_York")
ts := time.Date(2009, time.January, 20, 12, 5, 0, 0, tz)
gen := nomino.Timestamp(nomino.TimestampTime(ts), nomino.TimestampUTC())
conf := nomino.NewConfig(nomino.WithGenerator(gen))
s, _ := nomino.Make(conf)
fmt.Println(s)
// Output: 2009-01-20T17-05-00.txt
}

View file

@ -1,15 +0,0 @@
package nomino
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestTimestamp(t *testing.T) {
n := time.Now()
st, err := Timestamp()(nil)
assert.NoError(t, err)
assert.Equal(t, n.Format(FileTimestamp), st)
}

View file

@ -1,9 +1,17 @@
package nomino
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"errors"
"fmt"
"hash"
"strconv"
"time"
"github.com/google/uuid"
"github.com/gosimple/slug"
)
// Generator is a function that returns the "random" portion of the returned filename.
@ -56,3 +64,169 @@ func uuidGen(*Config) (string, error) {
func UUID() Generator {
return uuidGen
}
// FileTimestamp is the default format for WithTimestamp and WithTime
const FileTimestamp string = "2006-01-02_03-05-06-0700"
// Timestamp generates a a date and time for the current time.
// It is formatted accourding to FileTimestamp
func Timestamp() Generator {
return TimestampWithFormat(FileTimestamp)
}
// TimestampWithFormat generates a date and time for the current time with the supplied format.
func TimestampWithFormat(f string) Generator {
return FormattedTime(time.Now(), FileTimestamp)
}
// Time generates a date and time for the supplied time.
// It is formatted accourding to FileTimestamp
func Time(t time.Time) Generator {
return FormattedTime(t, FileTimestamp)
}
// FormattedTime generates a date and time for the supplied time with the supplied format.
func FormattedTime(t time.Time, f string) Generator {
return func(*Config) (string, error) {
return t.Format(f), nil
}
}
// FileTimestampNoTZ is the default format for WithTimestampUTC and WithTimeUTC
const FileTimestampNoTZ string = "2006-01-02_03-05-06"
// TimestampUTC generates a date and time for the current time in UTC without a timezone in the format.
func TimestampUTC() Generator {
return TimeUTC(time.Now())
}
// TimeUTC generates a date and time for the supplied time in UTC without a timezone in the format.
func TimeUTC(t time.Time) Generator {
return FormattedTime(t.UTC(), FileTimestampNoTZ)
}
// Incremental generates a name that is a series of integers starting at 0
func Incremental() Generator {
return IncrementalWithStartAndStep(0, 1)
}
// IncrementalFormat generates a name that is a series of integers starting at 0, formatted with Printf
// This is mostly likely useful with a format like "%02d"
func IncrementalFormat(format string) Generator {
return IncrementalFormatWithStartAndStep(0, 1, format)
}
// IncrementalWithStart generates a name that is a series of integers starting at the specified number
func IncrementalWithStart(start int) Generator {
return IncrementalWithStartAndStep(start, 1)
}
// IncrementalFormatWithStart generates a name that is a series of integers starting at the specified number, formatted with Printf
func IncrementalFormatWithStart(start int, format string) Generator {
return IncrementalFormatWithStartAndStep(start, 1, format)
}
// IncrementalWithStep generates a name that is a series of integers, starting at 0, and increasing the specified number each time
func IncrementalWithStep(step int) Generator {
return IncrementalWithStartAndStep(0, step)
}
// IncrementalFormatWithStep generates a name that is a series of integers, starting at 0, and increasing the specified number each time,
// formatted with Printf
func IncrementalFormatWithStep(step int, format string) Generator {
return IncrementalFormatWithStartAndStep(0, step, format)
}
func incrementalHelper(start, step int, cb func(int) string) Generator {
next := start
return func(*Config) (string, error) {
out := cb(next)
next += step
return out, nil
}
}
// InrementalWithStartAndStep generates a name that is a series of integers, starting at the specified number,
// and increasing the specified step each time
func IncrementalWithStartAndStep(start, step int) Generator {
return incrementalHelper(start, step, strconv.Itoa)
}
// IncrementalFormatWithStartAndStep generates a name that is a series of integers, starting at the specified number,
// and increasing the specified step each time, formatted with Printf
func IncrementalFormatWithStartAndStep(start, step int, format string) Generator {
return incrementalHelper(start, step, func(i int) string {
return fmt.Sprintf(format, i)
})
}
// ErrMissingOriginal is the error returned by Slug if there is no filename
var ErrMissingOriginal = errors.New("missing original filename")
func getOriginal(c *Config) (string, error) {
if c.original == "" {
return "", ErrMissingOriginal
}
name := c.original
c.original = ""
return name, nil
}
// Slug generates a name from the original filename.
// When this is used, the original filename will be removed from the final filename.
func Slug() Generator {
return func(c *Config) (string, error) {
name, err := getOriginal(c)
return slug.Make(name), err
}
}
// SlugWithLang generates a name from the original filename, accounting for the given language.
// When this is used, the original filename will be removed from the final filename.
func SlugWithLang(lang string) Generator {
return func(c *Config) (string, error) {
name, err := getOriginal(c)
return slug.MakeLang(name, lang), err
}
}
// HashingFunc is a function that generates a hash.Hash
type HashingFunc func() hash.Hash
//go:generate stringer -type=HashType
// HashType represents a particular hashing algorithm
type HashType uint8
const (
MD5 HashType = iota + 1
SHA1
SHA256
)
// ErrInvalidHashType is returned by the Hash generator when an invalid HashType is passed
var ErrInvalidHashType = errors.New("invalid hash type")
var hashMap = map[HashType]HashingFunc{
MD5: md5.New,
SHA1: sha1.New,
SHA256: sha256.New,
}
// Hash generates a name from a hash of the filename.
// When this is used, the original filename will be removed from the final filename.
func Hash(t HashType) Generator {
f, ok := hashMap[t]
return func(c *Config) (string, error) {
if !ok {
return "", fmt.Errorf("%w: %s", ErrInvalidHashType, t)
}
name, err := getOriginal(c)
if err != nil {
return "", err
}
hs := f()
hs.Write([]byte(name))
return fmt.Sprintf("%x", hs.Sum(nil)), nil
}
}

View file

@ -1,24 +1,17 @@
package nomino_test
package nomino
import (
"fmt"
import "fmt"
"codeberg.org/danjones000/nomino"
)
func ExampleWithGenerator_customGenerator() {
gen := func(*nomino.Config) (string, error) {
func ExampleWithGenerator_custom_generator() {
gen := func(*Config) (string, error) {
return "hello", nil
}
option := nomino.WithGenerator(gen)
option := WithGenerator(gen)
str, _ := nomino.Make(nomino.NewConfig(option))
str, _ := Make(NewConfig(option))
fmt.Println(str)
str, _ = nomino.Make(nomino.NewConfig(
option,
nomino.WithoutExtension(),
))
str, _ = Make(NewConfig(option, WithoutExtension()))
fmt.Println(str)
// Output:
@ -26,40 +19,175 @@ func ExampleWithGenerator_customGenerator() {
// hello
}
func ExampleMultiGeneratorInOrder() {
gen1 := func(*nomino.Config) (string, error) {
return "hello", nil
}
gen2 := func(*nomino.Config) (string, error) {
return "goodbye", nil
}
gen := nomino.MultiGeneratorInOrder(gen1, gen2)
option := nomino.WithGenerator(gen)
func ExampleIncremental() {
conf := NewConfig(WithPrefix("foo"), WithGenerator(Incremental()))
str, _ := nomino.Make(nomino.NewConfig(option))
str, _ := Make(conf)
fmt.Println(str)
str, _ = nomino.Make(nomino.NewConfig(option))
str, _ = Make(conf)
fmt.Println(str)
str, _ = nomino.Make(nomino.NewConfig(option))
str, _ = Make(conf)
fmt.Println(str)
// Output:
// hello.txt
// goodbye.txt
// hello.txt
// foo_0.txt
// foo_1.txt
// foo_2.txt
}
func ExampleUUID() {
option := nomino.WithGenerator(nomino.UUID())
func ExampleIncrementalWithStart() {
conf := NewConfig(WithPrefix("foo"), WithGenerator(IncrementalWithStart(42)))
str, _ := nomino.Make(nomino.NewConfig(option))
str, _ := Make(conf)
fmt.Println(str)
str, _ = nomino.Make(nomino.NewConfig(option))
str, _ = Make(conf)
fmt.Println(str)
str, _ = nomino.Make(nomino.NewConfig(option))
str, _ = Make(conf)
fmt.Println(str)
// Output:
// foo_42.txt
// foo_43.txt
// foo_44.txt
}
func ExampleIncrementalWithStep() {
conf := NewConfig(WithPrefix("foo"), WithGenerator(IncrementalWithStep(2)))
str, _ := Make(conf)
fmt.Println(str)
str, _ = Make(conf)
fmt.Println(str)
str, _ = Make(conf)
fmt.Println(str)
// Output:
// foo_0.txt
// foo_2.txt
// foo_4.txt
}
func ExampleIncrementalWithStartAndStep() {
conf := NewConfig(WithPrefix("foo"), WithGenerator(IncrementalWithStartAndStep(42, 2)))
str, _ := Make(conf)
fmt.Println(str)
str, _ = Make(conf)
fmt.Println(str)
str, _ = Make(conf)
fmt.Println(str)
// Output:
// foo_42.txt
// foo_44.txt
// foo_46.txt
}
func ExampleIncrementalFormat() {
conf := NewConfig(
WithPrefix("foo"),
WithGenerator(IncrementalFormat("%03d")),
)
str, _ := Make(conf)
fmt.Println(str)
str, _ = Make(conf)
fmt.Println(str)
str, _ = Make(conf)
fmt.Println(str)
// Output:
// foo_000.txt
// foo_001.txt
// foo_002.txt
}
func ExampleIncrementalFormatWithStart() {
conf := NewConfig(
WithPrefix("foo"),
WithGenerator(IncrementalFormatWithStart(9, "%02d")),
)
str, _ := Make(conf)
fmt.Println(str)
str, _ = Make(conf)
fmt.Println(str)
// Output:
// foo_09.txt
// foo_10.txt
}
func ExampleIncrementalFormatWithStep() {
conf := NewConfig(
WithPrefix("foo"),
WithGenerator(IncrementalFormatWithStep(10, "%02d")),
)
str, _ := Make(conf)
fmt.Println(str)
str, _ = Make(conf)
fmt.Println(str)
// Output:
// foo_00.txt
// foo_10.txt
}
func ExampleSlug() {
conf := NewConfig(WithGenerator(Slug()), WithOriginal("My name is Jimmy"))
str, _ := Make(conf)
fmt.Println(str)
// Output: my-name-is-jimmy.txt
}
func ExampleSlugWithLang() {
conf := NewConfig(WithGenerator(SlugWithLang("de")), WithOriginal("Diese & Dass"))
str, _ := Make(conf)
fmt.Println(str)
// Output: diese-und-dass.txt
}
func ExampleHash_mD5() {
conf := NewConfig(
WithOriginal("foobar"),
WithGenerator(Hash(MD5)),
)
str, _ := Make(conf)
fmt.Println(str)
// Output: 3858f62230ac3c915f300c664312c63f.txt
}
func ExampleHash_sHA1() {
conf := NewConfig(
WithOriginal("foobar"),
WithGenerator(Hash(SHA1)),
)
str, _ := Make(conf)
fmt.Println(str)
// Output: 8843d7f92416211de9ebb963ff4ce28125932878.txt
}
func ExampleHash_sHA256() {
conf := NewConfig(
WithOriginal("foobar"),
WithGenerator(Hash(SHA256)),
)
str, _ := Make(conf)
fmt.Println(str)
// Output: c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2.txt
}

View file

@ -2,7 +2,9 @@ package nomino
import (
"errors"
"fmt"
"testing"
"time"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
@ -82,3 +84,60 @@ func TestUUIDFail(t *testing.T) {
_, err := UUID()(nil)
assert.Equal(t, errors.New("sorry"), err)
}
func TestTimestamp(t *testing.T) {
n := time.Now()
st, err := Timestamp()(nil)
assert.NoError(t, err)
assert.Equal(t, n.Format(FileTimestamp), st)
}
func TestTime(t *testing.T) {
d := time.Date(1986, time.March, 28, 12, 0, 0, 0, time.UTC)
st, err := Time(d)(nil)
assert.NoError(t, err)
assert.Equal(t, d.Format(FileTimestamp), st)
}
func TestTimestampUTC(t *testing.T) {
n := time.Now()
st, err := TimestampUTC()(nil)
assert.NoError(t, err)
assert.Equal(t, n.UTC().Format(FileTimestampNoTZ), st)
}
func TestSlugMissingFilename(t *testing.T) {
conf := NewConfig(WithGenerator(Slug()))
st, err := conf.generator(&conf)
assert.Zero(t, st)
assert.ErrorIs(t, err, ErrMissingOriginal)
}
func TestSlugRemovesOriginal(t *testing.T) {
conf := NewConfig(WithGenerator(Slug()), WithOriginal("Hello, World"))
st, err := conf.generator(&conf)
assert.Zero(t, conf.original)
assert.Equal(t, "hello-world", st)
assert.NoError(t, err)
}
func TestHashBadHash(t *testing.T) {
conf := NewConfig(WithOriginal("foobar"), WithGenerator(Hash(0)))
st, err := conf.generator(&conf)
assert.Equal(t, "", st)
assert.ErrorIs(t, err, ErrInvalidHashType)
assert.ErrorContains(t, err, "invalid hash type: HashType(0)")
}
func TestHashMissingOriginal(t *testing.T) {
conf := NewConfig(WithGenerator(Hash(MD5)))
st, err := conf.generator(&conf)
assert.Equal(t, "", st)
assert.ErrorIs(t, err, ErrMissingOriginal)
}
func TestHashTypeStringer(t *testing.T) {
s := fmt.Sprintf("%s", MD5)
assert.Equal(t, "MD5", s)
}

View file

@ -1,4 +1,4 @@
// Code generated by "stringer -type=HashType -trimprefix=Hash"; DO NOT EDIT.
// Code generated by "stringer -type=HashType"; DO NOT EDIT.
package nomino
@ -8,9 +8,9 @@ func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[HashMD5-1]
_ = x[HashSHA1-2]
_ = x[HashSHA256-3]
_ = x[MD5-1]
_ = x[SHA1-2]
_ = x[SHA256-3]
}
const _HashType_name = "MD5SHA1SHA256"

14
make.go
View file

@ -5,21 +5,12 @@ import "fmt"
// Make generates a random filename. The behavior can be controlled by specifying Options
// In general, the final filename will be [prefix]_[generated_string]_[original_filename]_[suffix].[extension].
// If the name generator returns an error (generally, it shouldn't), that will be returned instead.
func Make(conf Config, opts ...Option) (string, error) {
for _, opt := range opts {
opt(&conf)
}
func Make(conf Config) (string, error) {
name, err := conf.generator(&conf)
if err != nil {
return "", err
}
seperateConf(&conf)
return fmt.Sprintf("%s%s%s%s%s", conf.prefix, name, conf.original, conf.suffix, conf.extension), nil
}
func seperateConf(conf *Config) {
if conf.prefix != "" {
conf.prefix += conf.separator
}
@ -28,5 +19,8 @@ func seperateConf(conf *Config) {
}
if conf.suffix != "" {
conf.suffix = conf.separator + conf.suffix
}
return fmt.Sprintf("%s%s%s%s%s", conf.prefix, name, conf.original, conf.suffix, conf.extension), nil
}

View file

@ -1,30 +1,9 @@
package nomino_test
package nomino
import (
"fmt"
"codeberg.org/danjones000/nomino"
)
import "fmt"
func ExampleMake_basic() {
// Use default config
out, _ := nomino.Make(nomino.NewConfig())
out, _ := Make(NewConfig())
fmt.Println(out)
}
func ExampleMake_withExtraOptions() {
gen := nomino.Incremental()
conf := nomino.NewConfig(
nomino.WithGenerator(gen),
nomino.WithPrefix("pre"),
)
st, _ := nomino.Make(conf, nomino.WithOriginal("foobar"))
fmt.Println(st)
st, _ = nomino.Make(conf, nomino.WithOriginal("baz"))
fmt.Println(st)
// Output:
// pre_0_foobar.txt
// pre_1_baz.txt
}

View file

@ -66,18 +66,3 @@ func TestMakeDoesntChangeConf(t *testing.T) {
assert.Equal(t, "foo.txt", st)
assert.NoError(t, err)
}
func TestMakeOptsDoesntChangeConf(t *testing.T) {
gen := Incremental()
conf := NewConfig(WithGenerator(gen), WithPrefix("pre"))
st, err := Make(conf, WithOriginal("foobar"))
assert.Equal(t, "", conf.original)
assert.Equal(t, "pre_0_foobar.txt", st)
assert.NoError(t, err)
st, err = Make(conf, WithOriginal("baz"))
assert.Equal(t, "", conf.original)
assert.Equal(t, "pre_1_baz.txt", st)
assert.NoError(t, err)
}

View file

@ -1,91 +1,11 @@
package nomino_test
package nomino
import (
"fmt"
"codeberg.org/danjones000/nomino"
)
func ExampleWithExtension() {
st, _ := nomino.Make(nomino.NewConfig(
nomino.WithExtension("xml"),
nomino.WithGenerator(nomino.Incremental()),
))
fmt.Println(st)
// Output: 0.xml
}
func ExampleWithoutExtension() {
st, _ := nomino.Make(nomino.NewConfig(
nomino.WithoutExtension(),
nomino.WithGenerator(nomino.Incremental()),
))
fmt.Println(st)
// Output: 0
}
func ExampleWithPrefix() {
conf := nomino.NewConfig(
nomino.WithPrefix("pref"),
nomino.WithGenerator(nomino.Incremental()),
)
st, _ := nomino.Make(conf)
fmt.Println(st)
st, _ = nomino.Make(conf)
fmt.Println(st)
// Output:
// pref_0.txt
// pref_1.txt
}
func ExampleWithSeparator() {
conf := nomino.NewConfig(
nomino.WithPrefix("pref"),
nomino.WithSeparator("---"),
nomino.WithGenerator(nomino.Incremental()),
)
st, _ := nomino.Make(conf)
fmt.Println(st)
st, _ = nomino.Make(conf)
fmt.Println(st)
// Output:
// pref---0.txt
// pref---1.txt
}
func ExampleWithSuffix() {
conf := nomino.NewConfig(
nomino.WithSuffix("suff"),
nomino.WithGenerator(nomino.Incremental()),
)
st, _ := nomino.Make(conf)
fmt.Println(st)
st, _ = nomino.Make(conf)
fmt.Println(st)
// Output:
// 0_suff.txt
// 1_suff.txt
}
func ExampleWithOriginal() {
st, _ := nomino.Make(nomino.NewConfig(
nomino.WithOriginal("Hello, World"),
nomino.WithGenerator(nomino.Incremental()),
))
fmt.Println(st)
// Output: 0_Hello, World.txt
}
import "fmt"
func ExampleWithOriginalSlug() {
st, _ := nomino.Make(nomino.NewConfig(
nomino.WithOriginalSlug("Hello, World"),
nomino.WithGenerator(nomino.Incremental()),
st, _ := Make(NewConfig(
WithOriginalSlug("Hello, World"),
WithGenerator(Incremental()),
))
fmt.Println(st)
@ -93,9 +13,9 @@ func ExampleWithOriginalSlug() {
}
func ExampleWithOriginalSlugLang() {
st, _ := nomino.Make(nomino.NewConfig(
nomino.WithOriginalSlugLang("Diese & Dass", "de"),
nomino.WithGenerator(nomino.Incremental()),
st, _ := Make(NewConfig(
WithOriginalSlugLang("Diese & Dass", "de"),
WithGenerator(Incremental()),
))
fmt.Println(st)

48
options_test.go Normal file
View file

@ -0,0 +1,48 @@
package nomino
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestWithOriginal(t *testing.T) {
var c Config
name := "foobar"
WithOriginal(name)(&c)
assert.Equal(t, name, c.original)
}
func TestWithPrefix(t *testing.T) {
var c Config
pref := "draft"
WithPrefix(pref)(&c)
assert.Equal(t, pref, c.prefix)
}
func TestWithSuffix(t *testing.T) {
var c Config
suff := "out"
WithSuffix(suff)(&c)
assert.Equal(t, suff, c.suffix)
}
func TestWithoutExtension(t *testing.T) {
c := Config{extension: ".foobar"}
WithoutExtension()(&c)
assert.Equal(t, "", c.extension)
}
func TestWithExtension(t *testing.T) {
var c Config
ext := "yaml"
WithExtension(ext)(&c)
assert.Equal(t, "."+ext, c.extension)
}
func TestWithSeparator(t *testing.T) {
var c Config
sep := "---"
WithSeparator(sep)(&c)
assert.Equal(t, sep, c.separator)
}