go.temporal.io/server@v1.23.0/common/primitives/uuid.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package primitives 26 27 import ( 28 "database/sql/driver" 29 "encoding/hex" 30 31 guuid "github.com/google/uuid" 32 "github.com/pborman/uuid" 33 ) 34 35 // UUID represents a 16-byte universally unique identifier 36 // this type is a wrapper around google/uuid with the following differences 37 // - type is a byte slice instead of [16]byte 38 // - db serialization converts uuid to bytes as opposed to string 39 type UUID []byte 40 41 // MustParseUUID returns a UUID parsed from the given string representation 42 // returns nil if the input is empty string 43 // panics if the given input is malformed 44 func MustParseUUID(s string) UUID { 45 if s == "" { 46 return nil 47 } 48 u := guuid.MustParse(s) 49 return u[:] 50 } 51 52 // ParseUUID returns a UUID parsed from the given string representation 53 // returns: 54 // - nil if the input is empty string 55 // - error if input is malformed 56 // - UUID object if input can be parsed and is valid 57 func ParseUUID(s string) (UUID, error) { 58 if s == "" { 59 return nil, nil 60 } 61 u, err := guuid.Parse(s) 62 63 if err != nil { 64 return nil, err 65 } 66 return u[:], nil 67 } 68 69 // MustValidateUUID parses and validates UUID contents from the given string representation 70 // returns empty string if the input is empty string 71 // panics if the given input is malformed 72 func MustValidateUUID(s string) string { 73 MustParseUUID(s) 74 return s 75 } 76 77 // ValidateUUID parses and validates UUID contents from the given string representation 78 // returns: 79 // - nil if the input is empty string 80 // - error if input is malformed 81 // - input if input can be parsed and is valid 82 func ValidateUUID(s string) (string, error) { 83 if s == "" { 84 return "", nil 85 } 86 _, err := guuid.Parse(s) 87 if err != nil { 88 return "", err 89 } 90 91 return s, nil 92 } 93 94 // NewUUID generates a new random UUID 95 func NewUUID() UUID { 96 return UUID(uuid.NewRandom()) 97 } 98 99 // Downcast returns the UUID as a byte slice. This is necessary when passing to type sensitive interfaces such as cql. 100 func (u UUID) Downcast() []byte { 101 return u 102 } 103 104 // UUIDPtr simply returns a pointer for the given value type 105 func UUIDPtr(u UUID) *UUID { 106 return &u 107 } 108 109 // String returns the 36 byte hexstring representation of this uuid 110 // return empty string if this uuid is nil 111 func (u UUID) String() string { 112 if len(u) != 16 { 113 return "" 114 } 115 var buf [36]byte 116 u.encodeHex(buf[:]) 117 return string(buf[:]) 118 } 119 120 // StringPtr returns a pointer to the 36 byte hexstring representation of this uuid 121 // return empty string if this uuid is nil 122 func (u UUID) StringPtr() *string { 123 if len(u) != 16 { 124 return stringPtr("") 125 } 126 var buf [36]byte 127 u.encodeHex(buf[:]) 128 return stringPtr(string(buf[:])) 129 } 130 131 func UUIDString(b []byte) string { 132 return UUID(b).String() 133 } 134 135 func stringPtr(v string) *string { 136 return &v 137 } 138 139 // Scan implements sql.Scanner interface to allow this type to be 140 // parsed transparently by database drivers 141 func (u *UUID) Scan(src interface{}) error { 142 if src == nil { 143 return nil 144 } 145 guuid := &guuid.UUID{} 146 if err := guuid.Scan(src); err != nil { 147 return err 148 } 149 *u = (*guuid)[:] 150 return nil 151 } 152 153 // Value implements sql.Valuer so that UUIDs can be written to databases 154 // transparently. This method returns a byte slice representation of uuid 155 func (u UUID) Value() (driver.Value, error) { 156 return []byte(u), nil 157 } 158 159 func (u UUID) encodeHex(dst []byte) { 160 hex.Encode(dst, u[:4]) 161 dst[8] = '-' 162 hex.Encode(dst[9:13], u[4:6]) 163 dst[13] = '-' 164 hex.Encode(dst[14:18], u[6:8]) 165 dst[18] = '-' 166 hex.Encode(dst[19:23], u[8:10]) 167 dst[23] = '-' 168 hex.Encode(dst[24:], u[10:]) 169 }