diff --git a/generators.go b/generators.go index 41b0674..e258716 100644 --- a/generators.go +++ b/generators.go @@ -6,6 +6,7 @@ import ( "time" "github.com/google/uuid" + "github.com/gosimple/slug" ) // Generator is a function that returns the "random" portion of the returned filename. @@ -123,3 +124,33 @@ func IncrementalWithStartAndStep(start, step int) Generator { return out, nil } } + +// 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 + } +} diff --git a/generators_examples_test.go b/generators_examples_test.go index c089c3f..bb9b4a8 100644 --- a/generators_examples_test.go +++ b/generators_examples_test.go @@ -90,3 +90,19 @@ func ExampleIncrementalWithStartAndStep() { // foo_44.txt // foo_46.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 +} diff --git a/generators_test.go b/generators_test.go index 8af03bc..fb28ce7 100644 --- a/generators_test.go +++ b/generators_test.go @@ -105,3 +105,18 @@ func TestTimestampUTC(t *testing.T) { 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) +} diff --git a/go.mod b/go.mod index de6af60..6917d49 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,13 @@ go 1.23.6 require ( github.com/google/uuid v1.6.0 + github.com/gosimple/slug v1.15.0 github.com/stretchr/testify v1.10.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gosimple/unidecode v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 14c872b..8638c59 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,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/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gosimple/slug v1.15.0 h1:wRZHsRrRcs6b0XnxMUBM6WK1U1Vg5B0R7VkIf1Xzobo= +github.com/gosimple/slug v1.15.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= +github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= diff --git a/make_test.go b/make_test.go index 8d98d45..28096ce 100644 --- a/make_test.go +++ b/make_test.go @@ -52,3 +52,15 @@ func TestMakeErr(t *testing.T) { assert.Zero(t, st) assert.ErrorIs(t, err, retErr) } + +func TestMakeDoesntChangeConf(t *testing.T) { + gen := func(c *Config) (string, error) { + c.original = "" + return "foo", nil + } + conf := NewConfig(WithGenerator(gen), WithOriginal("foobar")) + st, err := Make(conf) + assert.Equal(t, "foobar", conf.original) + assert.Equal(t, "foo.txt", st) + assert.NoError(t, err) +} diff --git a/options.go b/options.go index b51b756..c7e0338 100644 --- a/options.go +++ b/options.go @@ -1,6 +1,10 @@ package nomino -import "strings" +import ( + "strings" + + "github.com/gosimple/slug" +) // Option sets configuration parameters for Config. type Option func(c *Config) @@ -13,6 +17,22 @@ func WithOriginal(o string) Option { } } +// WithOriginal sets the original filename as a slug. +// This should not be used with the Slug Generator (as it would be redundant) +func WithOriginalSlug(o string) Option { + return func(c *Config) { + c.original = slug.Make(o) + } +} + +// WithOriginal sets the original filename as a slug, taking the language into account. +// This should not be used with the Slug Generator (as it would be redundant) +func WithOriginalSlugLang(o, lang string) Option { + return func(c *Config) { + c.original = slug.MakeLang(o, lang) + } +} + // WithPrefix sets a prefix for the generated name. func WithPrefix(p string) Option { return func(c *Config) { diff --git a/options_examples_test.go b/options_examples_test.go new file mode 100644 index 0000000..0c4e669 --- /dev/null +++ b/options_examples_test.go @@ -0,0 +1,23 @@ +package nomino + +import "fmt" + +func ExampleWithOriginalSlug() { + st, _ := Make(NewConfig( + WithOriginalSlug("Hello, World"), + WithGenerator(Incremental()), + )) + + fmt.Println(st) + // Output: 0_hello-world.txt +} + +func ExampleWithOriginalSlugLang() { + st, _ := Make(NewConfig( + WithOriginalSlugLang("Diese & Dass", "de"), + WithGenerator(Incremental()), + )) + + fmt.Println(st) + // Output: 0_diese-und-dass.txt +}