diff options
| author | Dave Henderson <dhenderson@gmail.com> | 2019-03-12 19:25:48 -0400 |
|---|---|---|
| committer | Dave Henderson <dhenderson@gmail.com> | 2019-03-14 20:38:46 -0400 |
| commit | 04edae94a4ade092a895770f268e5e6c9d69e117 (patch) | |
| tree | 47f5e1b6fcb7b3b45598747953307498a74a71b6 /funcs | |
| parent | a5706df3ccdb0d3018e7c75bdddff63d1e95e2df (diff) | |
New uuid namespace
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'funcs')
| -rw-r--r-- | funcs/uuid.go | 75 | ||||
| -rw-r--r-- | funcs/uuid_test.go | 89 |
2 files changed, 164 insertions, 0 deletions
diff --git a/funcs/uuid.go b/funcs/uuid.go new file mode 100644 index 00000000..f4578d17 --- /dev/null +++ b/funcs/uuid.go @@ -0,0 +1,75 @@ +package funcs + +import ( + "sync" + + "github.com/hairyhenderson/gomplate/conv" + + "github.com/google/uuid" +) + +var ( + uuidNS *UUIDFuncs + uuidNSInit sync.Once +) + +// UUIDNS - +func UUIDNS() *UUIDFuncs { + uuidNSInit.Do(func() { + uuidNS = &UUIDFuncs{} + }) + return uuidNS +} + +// AddUUIDFuncs - +func AddUUIDFuncs(f map[string]interface{}) { + f["uuid"] = UUIDNS +} + +// UUIDFuncs - +type UUIDFuncs struct{} + +// V1 - return a version 1 UUID (based on the current MAC Address and the +// current date/time). Use V4 instead in most cases. +func (f *UUIDFuncs) V1() (string, error) { + u, err := uuid.NewUUID() + if err != nil { + return "", err + } + return u.String(), nil +} + +// V4 - return a version 4 (random) UUID +func (f *UUIDFuncs) V4() (string, error) { + u, err := uuid.NewRandom() + if err != nil { + return "", err + } + return u.String(), nil +} + +// Nil - +func (f *UUIDFuncs) Nil() (string, error) { + return uuid.Nil.String(), nil +} + +// IsValid - checks if the given UUID is in the correct format. It does not +// validate whether the version or variant are correct. +func (f *UUIDFuncs) IsValid(in interface{}) (bool, error) { + _, err := f.Parse(in) + return err == nil, nil +} + +// Parse - parse a UUID for further manipulation or inspection. +// +// Both the standard UUID forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the +// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex +// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. +func (f *UUIDFuncs) Parse(in interface{}) (uuid.UUID, error) { + u, err := uuid.Parse(conv.ToString(in)) + if err != nil { + return uuid.Nil, err + } + return u, err +} diff --git a/funcs/uuid_test.go b/funcs/uuid_test.go new file mode 100644 index 00000000..7df826a5 --- /dev/null +++ b/funcs/uuid_test.go @@ -0,0 +1,89 @@ +package funcs + +import ( + "net/url" + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + uuidPattern = "^[[:xdigit:]]{8}-(?:[[:xdigit:]]{4}-){3}[[:xdigit:]]{12}$" + uuidV1Pattern = "^[[:xdigit:]]{8}-[[:xdigit:]]{4}-1[[:xdigit:]]{3}-[89ab][[:xdigit:]]{3}-[[:xdigit:]]{12}$" + uuidV4Pattern = "^[[:xdigit:]]{8}-[[:xdigit:]]{4}-4[[:xdigit:]]{3}-[89ab][[:xdigit:]]{3}-[[:xdigit:]]{12}$" +) + +func TestV1(t *testing.T) { + u := UUIDNS() + i, err := u.V1() + assert.NoError(t, err) + assert.Regexp(t, uuidV1Pattern, i) +} + +func TestV4(t *testing.T) { + u := UUIDNS() + i, err := u.V4() + assert.NoError(t, err) + assert.Regexp(t, uuidV4Pattern, i) +} + +func TestNil(t *testing.T) { + u := UUIDNS() + i, err := u.Nil() + assert.NoError(t, err) + assert.Equal(t, "00000000-0000-0000-0000-000000000000", i) +} + +func TestIsValid(t *testing.T) { + u := UUIDNS() + var in interface{} + in = false + i, err := u.IsValid(in) + assert.NoError(t, err) + assert.False(t, i) + + in = 12345 + i, err = u.IsValid(in) + assert.NoError(t, err) + assert.False(t, i) + + testdata := []interface{}{ + "123456781234123412341234567890ab", + "12345678-1234-1234-1234-1234567890ab", + "urn:uuid:12345678-1234-1234-1234-1234567890ab", + "{12345678-1234-1234-1234-1234567890ab}", + } + + for _, d := range testdata { + i, err = u.IsValid(d) + assert.NoError(t, err) + assert.True(t, i) + } +} + +func TestParse(t *testing.T) { + u := UUIDNS() + var in interface{} + in = false + _, err := u.Parse(in) + assert.Error(t, err) + + in = 12345 + _, err = u.Parse(in) + assert.Error(t, err) + + in = "12345678-1234-1234-1234-1234567890ab" + testdata := []interface{}{ + "123456781234123412341234567890ab", + "12345678-1234-1234-1234-1234567890ab", + "urn:uuid:12345678-1234-1234-1234-1234567890ab", + must(url.Parse("urn:uuid:12345678-1234-1234-1234-1234567890ab")), + "{12345678-1234-1234-1234-1234567890ab}", + } + + for _, d := range testdata { + uid, err := u.Parse(d) + assert.NoError(t, err) + assert.Equal(t, in, uid.String()) + } +} |
