summaryrefslogtreecommitdiff
path: root/funcs
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2019-03-12 19:25:48 -0400
committerDave Henderson <dhenderson@gmail.com>2019-03-14 20:38:46 -0400
commit04edae94a4ade092a895770f268e5e6c9d69e117 (patch)
tree47f5e1b6fcb7b3b45598747953307498a74a71b6 /funcs
parenta5706df3ccdb0d3018e7c75bdddff63d1e95e2df (diff)
New uuid namespace
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'funcs')
-rw-r--r--funcs/uuid.go75
-rw-r--r--funcs/uuid_test.go89
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())
+ }
+}