Merge pull request #16 from theory/driver.Valuer

Add support for driver.Valuer.
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..a6a98db
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+language: go
+
+go:
+  - 1.4.3
+  - 1.5.3
+  - release
+  - tip
+
+script:
+  - go test -v ./...
diff --git a/README.md b/README.md
index 0c31f01..f023d47 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,8 @@
 This project was automatically exported from code.google.com/p/go-uuid
 
-# uuid
+# uuid ![build status](https://travis-ci.org/pborman/uuid.svg?branch=master)
 The uuid package generates and inspects UUIDs based on [RFC 412](http://tools.ietf.org/html/rfc4122) and DCE 1.1: Authentication and Security Services. 
 
-
 ###### Install
 `go get github.com/pborman/uuid`
 
@@ -12,5 +11,3 @@
 
 Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: 
 http://godoc.org/github.com/pborman/uuid
-
-
diff --git a/json.go b/json.go
index 760580a..9dda1df 100644
--- a/json.go
+++ b/json.go
@@ -7,17 +7,21 @@
 import "errors"
 
 func (u UUID) MarshalJSON() ([]byte, error) {
-	if len(u) == 0 {
+	if len(u) != 16 {
 		return []byte(`""`), nil
 	}
-	return []byte(`"` + u.String() + `"`), nil
+	var js [38]byte
+	js[0] = '"'
+	encodeHex(js[1:], u)
+	js[37] = '"'
+	return js[:], nil
 }
 
 func (u *UUID) UnmarshalJSON(data []byte) error {
-	if len(data) == 0 || string(data) == `""` {
+	if string(data) == `""` {
 		return nil
 	}
-	if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
+	if data[0] != '"' {
 		return errors.New("invalid UUID format")
 	}
 	data = data[1 : len(data)-1]
diff --git a/json_test.go b/json_test.go
index b5eae09..2866b8d 100644
--- a/json_test.go
+++ b/json_test.go
@@ -30,3 +30,32 @@
 		t.Errorf("got %#v, want %#v", s2, s1)
 	}
 }
+
+func BenchmarkUUID_MarshalJSON(b *testing.B) {
+	x := &struct {
+		UUID UUID `json:"uuid"`
+	}{}
+	x.UUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
+	if x.UUID == nil {
+		b.Fatal("invalid uuid")
+	}
+	for i := 0; i < b.N; i++ {
+		js, err := json.Marshal(x)
+		if err != nil {
+			b.Fatalf("marshal json: %#v (%v)", js, err)
+		}
+	}
+}
+
+func BenchmarkUUID_UnmarshalJSON(b *testing.B) {
+	js := []byte(`{"uuid":"f47ac10b-58cc-0372-8567-0e02b2c3d479"}`)
+	var x *struct {
+		UUID UUID `json:"uuid"`
+	}
+	for i := 0; i < b.N; i++ {
+		err := json.Unmarshal(js, &x)
+		if err != nil {
+			b.Fatalf("marshal json: %#v (%v)", js, err)
+		}
+	}
+}
diff --git a/node.go b/node.go
index dd0a8ac..42d60da 100755
--- a/node.go
+++ b/node.go
@@ -4,9 +4,13 @@
 
 package uuid
 
-import "net"
+import (
+	"net"
+	"sync"
+)
 
 var (
+	nodeMu     sync.Mutex
 	interfaces []net.Interface // cached list of interfaces
 	ifname     string          // name of interface being used
 	nodeID     []byte          // hardware for version 1 UUIDs
@@ -16,6 +20,8 @@
 // derived.  The interface "user" is returned if the NodeID was set by
 // SetNodeID.
 func NodeInterface() string {
+	defer nodeMu.Unlock()
+	nodeMu.Lock()
 	return ifname
 }
 
@@ -26,6 +32,12 @@
 //
 // SetNodeInterface never fails when name is "".
 func SetNodeInterface(name string) bool {
+	defer nodeMu.Unlock()
+	nodeMu.Lock()
+	return setNodeInterface(name)
+}
+
+func setNodeInterface(name string) bool {
 	if interfaces == nil {
 		var err error
 		interfaces, err = net.Interfaces()
@@ -59,8 +71,10 @@
 // NodeID returns a slice of a copy of the current Node ID, setting the Node ID
 // if not already set.
 func NodeID() []byte {
+	defer nodeMu.Unlock()
+	nodeMu.Lock()
 	if nodeID == nil {
-		SetNodeInterface("")
+		setNodeInterface("")
 	}
 	nid := make([]byte, 6)
 	copy(nid, nodeID)
@@ -71,6 +85,8 @@
 // of id are used.  If id is less than 6 bytes then false is returned and the
 // Node ID is not set.
 func SetNodeID(id []byte) bool {
+	defer nodeMu.Unlock()
+	nodeMu.Lock()
 	if setNodeID(id) {
 		ifname = "user"
 		return true
diff --git a/sql_test.go b/sql_test.go
index 8cf695b..1030951 100644
--- a/sql_test.go
+++ b/sql_test.go
@@ -14,7 +14,8 @@
 	var byteTest []byte = Parse(stringTest)
 	var badTypeTest int = 6
 	var invalidTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d4"
-	var invalidByteTest []byte = Parse(invalidTest)
+
+	// sunny day tests
 
 	var uuid UUID
 	err := (&uuid).Scan(stringTest)
@@ -32,6 +33,8 @@
 		t.Fatal(err)
 	}
 
+	// bad type tests
+
 	err = (&uuid).Scan(badTypeTest)
 	if err == nil {
 		t.Error("int correctly parsed and shouldn't have")
@@ -40,6 +43,8 @@
 		t.Error("attempting to parse an int returned an incorrect error message")
 	}
 
+	// invalid/incomplete uuids
+
 	err = (&uuid).Scan(invalidTest)
 	if err == nil {
 		t.Error("invalid uuid was parsed without error")
@@ -48,13 +53,37 @@
 		t.Error("attempting to parse an invalid UUID returned an incorrect error message")
 	}
 
-	err = (&uuid).Scan(invalidByteTest)
+	err = (&uuid).Scan(byteTest[:len(byteTest)-2])
 	if err == nil {
 		t.Error("invalid byte uuid was parsed without error")
 	}
 	if !strings.Contains(err.Error(), "invalid UUID") {
 		t.Error("attempting to parse an invalid byte UUID returned an incorrect error message")
 	}
+
+	// empty tests
+
+	uuid = nil
+	var emptySlice []byte
+	err = (&uuid).Scan(emptySlice)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if uuid != nil {
+		t.Error("UUID was not nil after scanning empty byte slice")
+	}
+
+	uuid = nil
+	var emptyString string
+	err = (&uuid).Scan(emptyString)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if uuid != nil {
+		t.Error("UUID was not nil after scanning empty string")
+	}
 }
 
 func TestValue(t *testing.T) {
diff --git a/time.go b/time.go
index 7ebc9be..eedf242 100755
--- a/time.go
+++ b/time.go
@@ -23,7 +23,7 @@
 )
 
 var (
-	mu        sync.Mutex
+	timeMu    sync.Mutex
 	lasttime  uint64 // last time we returned
 	clock_seq uint16 // clock sequence for this run
 
@@ -43,8 +43,8 @@
 // clock sequence as well as adjusting the clock sequence as needed.  An error
 // is returned if the current time cannot be determined.
 func GetTime() (Time, uint16, error) {
-	defer mu.Unlock()
-	mu.Lock()
+	defer timeMu.Unlock()
+	timeMu.Lock()
 	return getTime()
 }
 
@@ -75,8 +75,8 @@
 // ClockSequence, GetTime, or NewUUID.  (section 4.2.1.1) sequence is generated
 // for
 func ClockSequence() int {
-	defer mu.Unlock()
-	mu.Lock()
+	defer timeMu.Unlock()
+	timeMu.Lock()
 	return clockSequence()
 }
 
@@ -90,8 +90,8 @@
 // SetClockSeq sets the clock sequence to the lower 14 bits of seq.  Setting to
 // -1 causes a new sequence to be generated.
 func SetClockSequence(seq int) {
-	defer mu.Unlock()
-	mu.Lock()
+	defer timeMu.Unlock()
+	timeMu.Lock()
 	setClockSequence(seq)
 }
 
diff --git a/util.go b/util.go
index de40b10..fc8e052 100644
--- a/util.go
+++ b/util.go
@@ -16,7 +16,7 @@
 }
 
 // xvalues returns the value of a byte as a hexadecimal digit or 255.
-var xvalues = []byte{
+var xvalues = [256]byte{
 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
diff --git a/uuid.go b/uuid.go
old mode 100755
new mode 100644
index 38e085b..c4482cd
--- a/uuid.go
+++ b/uuid.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"crypto/rand"
+	"encoding/hex"
 	"fmt"
 	"io"
 	"strings"
@@ -54,8 +55,8 @@
 	if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
 		return nil
 	}
-	uuid := make([]byte, 16)
-	for i, x := range []int{
+	var uuid [16]byte
+	for i, x := range [16]int{
 		0, 2, 4, 6,
 		9, 11,
 		14, 16,
@@ -67,7 +68,7 @@
 			uuid[i] = v
 		}
 	}
-	return uuid
+	return uuid[:]
 }
 
 // Equal returns true if uuid1 and uuid2 are equal.
@@ -78,23 +79,36 @@
 // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 // , or "" if uuid is invalid.
 func (uuid UUID) String() string {
-	if uuid == nil || len(uuid) != 16 {
+	if len(uuid) != 16 {
 		return ""
 	}
-	b := []byte(uuid)
-	return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x",
-		b[:4], b[4:6], b[6:8], b[8:10], b[10:])
+	var buf [36]byte
+	encodeHex(buf[:], uuid)
+	return string(buf[:])
 }
 
 // URN returns the RFC 2141 URN form of uuid,
 // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,  or "" if uuid is invalid.
 func (uuid UUID) URN() string {
-	if uuid == nil || len(uuid) != 16 {
+	if len(uuid) != 16 {
 		return ""
 	}
-	b := []byte(uuid)
-	return fmt.Sprintf("urn:uuid:%08x-%04x-%04x-%04x-%012x",
-		b[:4], b[4:6], b[6:8], b[8:10], b[10:])
+	var buf [36 + 9]byte
+	copy(buf[:], "urn:uuid:")
+	encodeHex(buf[9:], uuid)
+	return string(buf[:])
+}
+
+func encodeHex(dst []byte, uuid UUID) {
+	hex.Encode(dst[:], uuid[:4])
+	dst[8] = '-'
+	hex.Encode(dst[9:13], uuid[4:6])
+	dst[13] = '-'
+	hex.Encode(dst[14:18], uuid[6:8])
+	dst[18] = '-'
+	hex.Encode(dst[19:23], uuid[8:10])
+	dst[23] = '-'
+	hex.Encode(dst[24:], uuid[10:])
 }
 
 // Variant returns the variant encoded in uuid.  It returns Invalid if
@@ -113,7 +127,6 @@
 	default:
 		return Reserved
 	}
-	panic("unreachable")
 }
 
 // Version returns the version of uuid.  It returns false if uuid is not
diff --git a/uuid_test.go b/uuid_test.go
old mode 100755
new mode 100644
index 417ebeb..3835cc8
--- a/uuid_test.go
+++ b/uuid_test.go
@@ -112,7 +112,7 @@
 			t.Errorf("%x: %v: not a stringer", x, v)
 		} else if s := v.String(); s != tt.name {
 			v, _ := tt.c.(int)
-			t.Errorf("%x: Constant %T:%d gives %q, expected %q\n", x, tt.c, v, s, tt.name)
+			t.Errorf("%x: Constant %T:%d gives %q, expected %q", x, tt.c, v, s, tt.name)
 		}
 	}
 }
@@ -123,14 +123,14 @@
 		uuid := NewRandom()
 		s := uuid.String()
 		if m[s] {
-			t.Errorf("NewRandom returned duplicated UUID %s\n", s)
+			t.Errorf("NewRandom returned duplicated UUID %s", s)
 		}
 		m[s] = true
 		if v, _ := uuid.Version(); v != 4 {
-			t.Errorf("Random UUID of version %s\n", v)
+			t.Errorf("Random UUID of version %s", v)
 		}
 		if uuid.Variant() != RFC4122 {
-			t.Errorf("Random UUID is variant %d\n", uuid.Variant())
+			t.Errorf("Random UUID is variant %d", uuid.Variant())
 		}
 	}
 }
@@ -140,19 +140,19 @@
 	for x := 1; x < 32; x++ {
 		s := New()
 		if m[s] {
-			t.Errorf("New returned duplicated UUID %s\n", s)
+			t.Errorf("New returned duplicated UUID %s", s)
 		}
 		m[s] = true
 		uuid := Parse(s)
 		if uuid == nil {
-			t.Errorf("New returned %q which does not decode\n", s)
+			t.Errorf("New returned %q which does not decode", s)
 			continue
 		}
 		if v, _ := uuid.Version(); v != 4 {
-			t.Errorf("Random UUID of version %s\n", v)
+			t.Errorf("Random UUID of version %s", v)
 		}
 		if uuid.Variant() != RFC4122 {
-			t.Errorf("Random UUID is variant %d\n", uuid.Variant())
+			t.Errorf("Random UUID is variant %d", uuid.Variant())
 		}
 	}
 }
@@ -160,7 +160,7 @@
 func clockSeq(t *testing.T, uuid UUID) int {
 	seq, ok := uuid.ClockSequence()
 	if !ok {
-		t.Fatalf("%s: invalid clock sequence\n", uuid)
+		t.Fatalf("%s: invalid clock sequence", uuid)
 	}
 	return seq
 }
@@ -179,7 +179,7 @@
 	uuid2 := NewUUID()
 
 	if clockSeq(t, uuid1) != clockSeq(t, uuid2) {
-		t.Errorf("clock sequence %d != %d\n", clockSeq(t, uuid1), clockSeq(t, uuid2))
+		t.Errorf("clock sequence %d != %d", clockSeq(t, uuid1), clockSeq(t, uuid2))
 	}
 
 	SetClockSequence(-1)
@@ -192,13 +192,13 @@
 		uuid2 = NewUUID()
 	}
 	if clockSeq(t, uuid1) == clockSeq(t, uuid2) {
-		t.Errorf("Duplicate clock sequence %d\n", clockSeq(t, uuid1))
+		t.Errorf("Duplicate clock sequence %d", clockSeq(t, uuid1))
 	}
 
 	SetClockSequence(0x1234)
 	uuid1 = NewUUID()
 	if seq := clockSeq(t, uuid1); seq != 0x1234 {
-		t.Errorf("%s: expected seq 0x1234 got 0x%04x\n", uuid1, seq)
+		t.Errorf("%s: expected seq 0x1234 got 0x%04x", uuid1, seq)
 	}
 }
 
@@ -213,15 +213,15 @@
 		0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2,
 	}
 	if v := data.String(); v != text {
-		t.Errorf("%x: encoded to %s, expected %s\n", data, v, text)
+		t.Errorf("%x: encoded to %s, expected %s", data, v, text)
 	}
 	if v := data.URN(); v != urn {
-		t.Errorf("%x: urn is %s, expected %s\n", data, v, urn)
+		t.Errorf("%x: urn is %s, expected %s", data, v, urn)
 	}
 
 	uuid := Parse(text)
 	if !Equal(uuid, data) {
-		t.Errorf("%s: decoded to %s, expected %s\n", text, uuid, data)
+		t.Errorf("%s: decoded to %s, expected %s", text, uuid, data)
 	}
 }
 
@@ -230,30 +230,30 @@
 	uuid2 := NewUUID()
 
 	if Equal(uuid1, uuid2) {
-		t.Errorf("%s:duplicate uuid\n", uuid1)
+		t.Errorf("%s:duplicate uuid", uuid1)
 	}
 	if v, _ := uuid1.Version(); v != 1 {
-		t.Errorf("%s: version %s expected 1\n", uuid1, v)
+		t.Errorf("%s: version %s expected 1", uuid1, v)
 	}
 	if v, _ := uuid2.Version(); v != 1 {
-		t.Errorf("%s: version %s expected 1\n", uuid2, v)
+		t.Errorf("%s: version %s expected 1", uuid2, v)
 	}
 	n1 := uuid1.NodeID()
 	n2 := uuid2.NodeID()
 	if !bytes.Equal(n1, n2) {
-		t.Errorf("Different nodes %x != %x\n", n1, n2)
+		t.Errorf("Different nodes %x != %x", n1, n2)
 	}
 	t1, ok := uuid1.Time()
 	if !ok {
-		t.Errorf("%s: invalid time\n", uuid1)
+		t.Errorf("%s: invalid time", uuid1)
 	}
 	t2, ok := uuid2.Time()
 	if !ok {
-		t.Errorf("%s: invalid time\n", uuid2)
+		t.Errorf("%s: invalid time", uuid2)
 	}
 	q1, ok := uuid1.ClockSequence()
 	if !ok {
-		t.Errorf("%s: invalid clock sequence\n", uuid1)
+		t.Errorf("%s: invalid clock sequence", uuid1)
 	}
 	q2, ok := uuid2.ClockSequence()
 	if !ok {
@@ -262,11 +262,53 @@
 
 	switch {
 	case t1 == t2 && q1 == q2:
-		t.Errorf("time stopped\n")
+		t.Error("time stopped")
 	case t1 > t2 && q1 == q2:
-		t.Errorf("time reversed\n")
+		t.Error("time reversed")
 	case t1 < t2 && q1 != q2:
-		t.Errorf("clock sequence chaned unexpectedly\n")
+		t.Error("clock sequence chaned unexpectedly")
+	}
+}
+
+func TestNode(t *testing.T) {
+	// This test is mostly to make sure we don't leave nodeMu locked.
+	ifname = ""
+	if ni := NodeInterface(); ni != "" {
+		t.Errorf("NodeInterface got %q, want %q", ni, "")
+	}
+	if SetNodeInterface("xyzzy") {
+		t.Error("SetNodeInterface succeeded on a bad interface name")
+	}
+	if !SetNodeInterface("") {
+		t.Error("SetNodeInterface failed")
+	}
+	if ni := NodeInterface(); ni == "" {
+		t.Error("NodeInterface returned an empty string")
+	}
+
+	ni := NodeID()
+	if len(ni) != 6 {
+		t.Errorf("ni got %d bytes, want 6", len(ni))
+	}
+	hasData := false
+	for _, b := range ni {
+		if b != 0 {
+			hasData = true
+		}
+	}
+	if !hasData {
+		t.Error("nodeid is all zeros")
+	}
+
+	id := []byte{1,2,3,4,5,6,7,8}
+	SetNodeID(id)
+	ni = NodeID()
+	if !bytes.Equal(ni, id[:6]) {
+		t.Errorf("got nodeid %v, want %v", ni, id[:6])
+	}
+
+	if ni := NodeInterface(); ni != "user" {
+		t.Errorf("got inteface %q, want %q", ni, "user")
 	}
 }
 
@@ -284,10 +326,10 @@
 			t.Errorf("Got time %v, want %v", c, want)
 		}
 	} else {
-		t.Errorf("%s: bad time\n", uuid)
+		t.Errorf("%s: bad time", uuid)
 	}
 	if !bytes.Equal(node, uuid.NodeID()) {
-		t.Errorf("Expected node %v got %v\n", node, uuid.NodeID())
+		t.Errorf("Expected node %v got %v", node, uuid.NodeID())
 	}
 }
 
@@ -295,7 +337,7 @@
 	uuid := NewMD5(NameSpace_DNS, []byte("python.org")).String()
 	want := "6fa459ea-ee8a-3ca4-894e-db77e160355e"
 	if uuid != want {
-		t.Errorf("MD5: got %q expected %q\n", uuid, want)
+		t.Errorf("MD5: got %q expected %q", uuid, want)
 	}
 }
 
@@ -303,7 +345,7 @@
 	uuid := NewSHA1(NameSpace_DNS, []byte("python.org")).String()
 	want := "886313e1-3b8a-5372-9b90-0c9aee199e5d"
 	if uuid != want {
-		t.Errorf("SHA1: got %q expected %q\n", uuid, want)
+		t.Errorf("SHA1: got %q expected %q", uuid, want)
 	}
 }
 
@@ -312,49 +354,49 @@
 	SetNodeInterface("")
 	s := NodeInterface()
 	if s == "" || s == "user" {
-		t.Errorf("NodeInterface %q after SetInteface\n", s)
+		t.Errorf("NodeInterface %q after SetInteface", s)
 	}
 	node1 := NodeID()
 	if node1 == nil {
-		t.Errorf("NodeID nil after SetNodeInterface\n", s)
+		t.Error("NodeID nil after SetNodeInterface", s)
 	}
 	SetNodeID(nid)
 	s = NodeInterface()
 	if s != "user" {
-		t.Errorf("Expected NodeInterface %q got %q\n", "user", s)
+		t.Errorf("Expected NodeInterface %q got %q", "user", s)
 	}
 	node2 := NodeID()
 	if node2 == nil {
-		t.Errorf("NodeID nil after SetNodeID\n", s)
+		t.Error("NodeID nil after SetNodeID", s)
 	}
 	if bytes.Equal(node1, node2) {
-		t.Errorf("NodeID not changed after SetNodeID\n", s)
+		t.Error("NodeID not changed after SetNodeID", s)
 	} else if !bytes.Equal(nid, node2) {
-		t.Errorf("NodeID is %x, expected %x\n", node2, nid)
+		t.Errorf("NodeID is %x, expected %x", node2, nid)
 	}
 }
 
 func testDCE(t *testing.T, name string, uuid UUID, domain Domain, id uint32) {
 	if uuid == nil {
-		t.Errorf("%s failed\n", name)
+		t.Errorf("%s failed", name)
 		return
 	}
 	if v, _ := uuid.Version(); v != 2 {
-		t.Errorf("%s: %s: expected version 2, got %s\n", name, uuid, v)
+		t.Errorf("%s: %s: expected version 2, got %s", name, uuid, v)
 		return
 	}
 	if v, ok := uuid.Domain(); !ok || v != domain {
 		if !ok {
-			t.Errorf("%s: %d: Domain failed\n", name, uuid)
+			t.Errorf("%s: %d: Domain failed", name, uuid)
 		} else {
-			t.Errorf("%s: %s: expected domain %d, got %d\n", name, uuid, domain, v)
+			t.Errorf("%s: %s: expected domain %d, got %d", name, uuid, domain, v)
 		}
 	}
 	if v, ok := uuid.Id(); !ok || v != id {
 		if !ok {
-			t.Errorf("%s: %d: Id failed\n", name, uuid)
+			t.Errorf("%s: %d: Id failed", name, uuid)
 		} else {
-			t.Errorf("%s: %s: expected id %d, got %d\n", name, uuid, id, v)
+			t.Errorf("%s: %s: expected id %d, got %d", name, uuid, id, v)
 		}
 	}
 }
@@ -379,12 +421,51 @@
 	uuid1 := New()
 	uuid2 := New()
 	if uuid1 != uuid2 {
-		t.Errorf("execpted duplicates, got %q and %q\n", uuid1, uuid2)
+		t.Errorf("execpted duplicates, got %q and %q", uuid1, uuid2)
 	}
 	SetRand(nil)
 	uuid1 = New()
 	uuid2 = New()
 	if uuid1 == uuid2 {
-		t.Errorf("unexecpted duplicates, got %q\n", uuid1)
+		t.Errorf("unexecpted duplicates, got %q", uuid1)
+	}
+}
+
+func BenchmarkParse(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
+		if uuid == nil {
+			b.Fatal("invalid uuid")
+		}
+	}
+}
+
+func BenchmarkNew(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		New()
+	}
+}
+
+func BenchmarkUUID_String(b *testing.B) {
+	uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
+	if uuid == nil {
+		b.Fatal("invalid uuid")
+	}
+	for i := 0; i < b.N; i++ {
+		if uuid.String() == "" {
+			b.Fatal("invalid uuid")
+		}
+	}
+}
+
+func BenchmarkUUID_URN(b *testing.B) {
+	uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479")
+	if uuid == nil {
+		b.Fatal("invalid uuid")
+	}
+	for i := 0; i < b.N; i++ {
+		if uuid.URN() == "" {
+			b.Fatal("invalid uuid")
+		}
 	}
 }