package pgtype
import (
)
type UUIDScanner interface {
ScanUUID(v UUID) error
}
type UUIDValuer interface {
UUIDValue() (UUID, error)
}
type UUID struct {
Bytes [16]byte
Valid bool
}
func ( *UUID) ( UUID) error {
* =
return nil
}
func ( UUID) () (UUID, error) {
return , nil
}
func ( string) ( [16]byte, error) {
switch len() {
case 36:
= [0:8] + [9:13] + [14:18] + [19:23] + [24:]
case 32:
default:
return , fmt.Errorf("cannot parse UUID %v", )
}
, := hex.DecodeString()
if != nil {
return ,
}
copy([:], )
return ,
}
func ( [16]byte) string {
var [36]byte
hex.Encode([0:8], [:4])
[8] = '-'
hex.Encode([9:13], [4:6])
[13] = '-'
hex.Encode([14:18], [6:8])
[18] = '-'
hex.Encode([19:23], [8:10])
[23] = '-'
hex.Encode([24:], [10:])
return string([:])
}
func ( *UUID) ( any) error {
if == nil {
* = UUID{}
return nil
}
switch src := .(type) {
case string:
, := parseUUID()
if != nil {
return
}
* = UUID{Bytes: , Valid: true}
return nil
}
return fmt.Errorf("cannot scan %T", )
}
func ( UUID) () (driver.Value, error) {
if !.Valid {
return nil, nil
}
return encodeUUID(.Bytes), nil
}
func ( UUID) () string {
if !.Valid {
return ""
}
return encodeUUID(.Bytes)
}
func ( UUID) () ([]byte, error) {
if !.Valid {
return []byte("null"), nil
}
var bytes.Buffer
.WriteByte('"')
.WriteString(encodeUUID(.Bytes))
.WriteByte('"')
return .Bytes(), nil
}
func ( *UUID) ( []byte) error {
if bytes.Equal(, []byte("null")) {
* = UUID{}
return nil
}
if len() != 38 {
return fmt.Errorf("invalid length for UUID: %v", len())
}
, := parseUUID(string([1 : len()-1]))
if != nil {
return
}
* = UUID{Bytes: , Valid: true}
return nil
}
type UUIDCodec struct{}
func (UUIDCodec) ( int16) bool {
return == TextFormatCode || == BinaryFormatCode
}
func (UUIDCodec) () int16 {
return BinaryFormatCode
}
func (UUIDCodec) ( *Map, uint32, int16, any) EncodePlan {
if , := .(UUIDValuer); ! {
return nil
}
switch {
case BinaryFormatCode:
return encodePlanUUIDCodecBinaryUUIDValuer{}
case TextFormatCode:
return encodePlanUUIDCodecTextUUIDValuer{}
}
return nil
}
type encodePlanUUIDCodecBinaryUUIDValuer struct{}
func (encodePlanUUIDCodecBinaryUUIDValuer) ( any, []byte) ( []byte, error) {
, := .(UUIDValuer).UUIDValue()
if != nil {
return nil,
}
if !.Valid {
return nil, nil
}
return append(, .Bytes[:]...), nil
}
type encodePlanUUIDCodecTextUUIDValuer struct{}
func (encodePlanUUIDCodecTextUUIDValuer) ( any, []byte) ( []byte, error) {
, := .(UUIDValuer).UUIDValue()
if != nil {
return nil,
}
if !.Valid {
return nil, nil
}
return append(, encodeUUID(.Bytes)...), nil
}
func (UUIDCodec) ( *Map, uint32, int16, any) ScanPlan {
switch {
case BinaryFormatCode:
switch .(type) {
case UUIDScanner:
return scanPlanBinaryUUIDToUUIDScanner{}
case TextScanner:
return scanPlanBinaryUUIDToTextScanner{}
}
case TextFormatCode:
switch .(type) {
case UUIDScanner:
return scanPlanTextAnyToUUIDScanner{}
}
}
return nil
}
type scanPlanBinaryUUIDToUUIDScanner struct{}
func (scanPlanBinaryUUIDToUUIDScanner) ( []byte, any) error {
:= ().(UUIDScanner)
if == nil {
return .ScanUUID(UUID{})
}
if len() != 16 {
return fmt.Errorf("invalid length for UUID: %v", len())
}
:= UUID{Valid: true}
copy(.Bytes[:], )
return .ScanUUID()
}
type scanPlanBinaryUUIDToTextScanner struct{}
func (scanPlanBinaryUUIDToTextScanner) ( []byte, any) error {
:= ().(TextScanner)
if == nil {
return .ScanText(Text{})
}
if len() != 16 {
return fmt.Errorf("invalid length for UUID: %v", len())
}
var [16]byte
copy([:], )
return .ScanText(Text{String: encodeUUID(), Valid: true})
}
type scanPlanTextAnyToUUIDScanner struct{}
func (scanPlanTextAnyToUUIDScanner) ( []byte, any) error {
:= ().(UUIDScanner)
if == nil {
return .ScanUUID(UUID{})
}
, := parseUUID(string())
if != nil {
return
}
return .ScanUUID(UUID{Bytes: , Valid: true})
}
func ( UUIDCodec) ( *Map, uint32, int16, []byte) (driver.Value, error) {
if == nil {
return nil, nil
}
var UUID
:= codecScan(, , , , , &)
if != nil {
return nil,
}
return encodeUUID(.Bytes), nil
}
func ( UUIDCodec) ( *Map, uint32, int16, []byte) (any, error) {
if == nil {
return nil, nil
}
var UUID
:= codecScan(, , , , , &)
if != nil {
return nil,
}
return .Bytes, nil
}