infra
/
goutils
Archived
1
0
Fork 0
This repository has been archived on 2022-04-06. You can view files and clone it, but cannot push or open issues or pull requests.
goutils/misc/uuid.go

119 lines
2.2 KiB
Go

package misc
import (
"bytes"
"database/sql/driver"
"encoding/hex"
"errors"
"github.com/NebulousLabs/fastrand"
"fmt"
)
type UUID [16]byte
func (u UUID) Marshal() ([]byte, error) {
return u[:], nil
}
func (u UUID) MarshalTo(buf []byte) (n int, err error) {
if len(u) == 0 {
return 0, nil
}
copy(buf, u[:])
return len(u), nil
}
func (u *UUID) Unmarshal(buf []byte) error {
if len(buf) != 16 {
return fmt.Errorf("invalid UUID (got %d bytes)", len(buf))
}
copy(u[:], buf)
return nil
}
func (u UUID) Compare(other UUID) int {
return bytes.Compare(u[:], other[:])
}
func (u UUID) Equal(other UUID) bool {
return u.Compare(other) == 0
}
func (u *UUID) UnmarshalJSON(from []byte) error {
quote := []byte("\"")
quoteSize := len(quote)
if len(from) < quoteSize*2 {
return errors.New("invalid quote notation")
}
if !bytes.HasPrefix(from, quote) || !bytes.HasSuffix(from, quote) {
return errors.New("invalid quote notation")
} else if err := u.Unmarshal(from[quoteSize:len(from)-quoteSize]); err != nil {
return err
}
return nil
}
func (u UUID) MarshalJSON() ([]byte, error) {
var buffer bytes.Buffer
buffer.WriteRune('"')
buffer.WriteString(hex.EncodeToString(u[:]))
buffer.WriteRune('"')
return buffer.Bytes(), nil
}
func (u *UUID) Size() int {
if u == nil {
return 0
}
if len(*u) == 0 {
return 0
}
return 16
}
func NewUUID() (u UUID) {
newObj := UUID{}
newObj.Random()
return newObj
}
func (u *UUID) UUIDFromHexString(buf []byte) (error) {
hexBuf := make([]byte, hex.DecodedLen(len(buf)))
if _, err := hex.Decode(hexBuf, buf); err != nil {
return err
} else if err := u.Unmarshal(hexBuf); err != nil {
return err
}
return nil
}
func (u UUID) ToHexString() (string) {
return hex.EncodeToString(u[:])
}
// Scan implements the Scanner interface.
func (u *UUID) Scan(src interface{}) error {
if src == nil {
return nil
}
b, ok := src.([]byte)
if !ok {
return errors.New("Scan source was not []bytes")
}
u.UUIDFromHexString(b)
return nil
}
// Value implements the driver Valuer interface.
func (u UUID) Value() (driver.Value, error) {
return u.ToHexString(), nil
}
func (u UUID) Random() {
fastrand.Read(u[:])
u[6] = (u[6] & 0x0f) | 0x40 // Version 4
u[8] = (u[8] & 0x3f) | 0x80 // Variant is 10
}