Skip to content

Commit

Permalink
Merge branch 'master' into no_v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Xe committed Mar 23, 2019
2 parents 775d98f + 2593f3d commit 6486973
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 2 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Expand Up @@ -6,13 +6,12 @@ go:
- 1.9.x
- 1.10.x
- 1.11.x
- 1.12.x
- tip
matrix:
allow_failures:
- go: tip
fast_finish: true
env:
- GO111MODULE=on
before_install:
- go get golang.org/x/tools/cmd/cover
script:
Expand Down
61 changes: 61 additions & 0 deletions uuid.go
Expand Up @@ -41,6 +41,8 @@ import (
"encoding/binary"
"encoding/hex"
"fmt"
"io"
"strings"
"time"
)

Expand Down Expand Up @@ -164,6 +166,65 @@ func (u UUID) String() string {
return string(buf)
}

// Format implements fmt.Formatter for UUID values.
//
// The behavior is as follows:
// The 'x' and 'X' verbs output only the hex digits of the UUID, using a-f for 'x' and A-F for 'X'.
// The 'v', '+v', 's' and 'q' verbs return the canonical RFC-4122 string representation.
// The 'S' verb returns the RFC-4122 format, but with capital hex digits.
// The '#v' verb returns the "Go syntax" representation, which is a 16 byte array initializer.
// All other verbs not handled directly by the fmt package (like '%p') are unsupported and will return
// "%!verb(uuid.UUID=value)" as recommended by the fmt package.
func (u UUID) Format(f fmt.State, c rune) {
switch c {
case 'x', 'X':
s := hex.EncodeToString(u.Bytes())
if c == 'X' {
s = strings.Map(toCapitalHexDigits, s)
}
_, _ = io.WriteString(f, s)
case 'v':
var s string
if f.Flag('#') {
s = fmt.Sprintf("%#v", [Size]byte(u))
} else {
s = u.String()
}
_, _ = io.WriteString(f, s)
case 's', 'S':
s := u.String()
if c == 'S' {
s = strings.Map(toCapitalHexDigits, s)
}
_, _ = io.WriteString(f, s)
case 'q':
_, _ = io.WriteString(f, `"`+u.String()+`"`)
default:
// invalid/unsupported format verb
fmt.Fprintf(f, "%%!%c(uuid.UUID=%s)", c, u.String())
}
}

func toCapitalHexDigits(ch rune) rune {
// convert a-f hex digits to A-F
switch ch {
case 'a':
return 'A'
case 'b':
return 'B'
case 'c':
return 'C'
case 'd':
return 'D'
case 'e':
return 'E'
case 'f':
return 'F'
default:
return ch
}
}

// SetVersion sets the version bits.
func (u *UUID) SetVersion(v byte) {
u[6] = (u[6] & 0x0f) | (v << 4)
Expand Down
38 changes: 38 additions & 0 deletions uuid_test.go
Expand Up @@ -35,6 +35,7 @@ func TestUUID(t *testing.T) {
t.Run("Variant", testUUIDVariant)
t.Run("SetVersion", testUUIDSetVersion)
t.Run("SetVariant", testUUIDSetVariant)
t.Run("Format", testUUIDFormat)
}

func testUUIDBytes(t *testing.T) {
Expand Down Expand Up @@ -114,6 +115,43 @@ func testUUIDSetVariant(t *testing.T) {
}
}

func testUUIDFormat(t *testing.T) {
val := Must(FromString("12345678-90ab-cdef-1234-567890abcdef"))
tests := []struct {
u UUID
f string
want string
}{
{u: val, f: "%s", want: "12345678-90ab-cdef-1234-567890abcdef"},
{u: val, f: "%S", want: "12345678-90AB-CDEF-1234-567890ABCDEF"},
{u: val, f: "%q", want: `"12345678-90ab-cdef-1234-567890abcdef"`},
{u: val, f: "%x", want: "1234567890abcdef1234567890abcdef"},
{u: val, f: "%X", want: "1234567890ABCDEF1234567890ABCDEF"},
{u: val, f: "%v", want: "12345678-90ab-cdef-1234-567890abcdef"},
{u: val, f: "%+v", want: "12345678-90ab-cdef-1234-567890abcdef"},
{u: val, f: "%#v", want: "[16]uint8{0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef}"},
{u: val, f: "%T", want: "uuid.UUID"},
{u: val, f: "%t", want: "%!t(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%b", want: "%!b(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%c", want: "%!c(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%d", want: "%!d(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%e", want: "%!e(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%E", want: "%!E(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%f", want: "%!f(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%F", want: "%!F(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%g", want: "%!g(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%G", want: "%!G(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%o", want: "%!o(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
{u: val, f: "%U", want: "%!U(uuid.UUID=12345678-90ab-cdef-1234-567890abcdef)"},
}
for _, tt := range tests {
got := fmt.Sprintf(tt.f, tt.u)
if tt.want != got {
t.Errorf(`Format("%s") got %s, want %s`, tt.f, got, tt.want)
}
}
}

func TestMust(t *testing.T) {
sentinel := fmt.Errorf("uuid: sentinel error")
defer func() {
Expand Down

0 comments on commit 6486973

Please sign in to comment.