github.com/jackc/pgx/v5@v5.5.5/pgtype/macaddr.go (about) 1 package pgtype 2 3 import ( 4 "database/sql/driver" 5 "net" 6 ) 7 8 type MacaddrCodec struct{} 9 10 func (MacaddrCodec) FormatSupported(format int16) bool { 11 return format == TextFormatCode || format == BinaryFormatCode 12 } 13 14 func (MacaddrCodec) PreferredFormat() int16 { 15 return BinaryFormatCode 16 } 17 18 func (MacaddrCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { 19 switch format { 20 case BinaryFormatCode: 21 switch value.(type) { 22 case net.HardwareAddr: 23 return encodePlanMacaddrCodecBinaryHardwareAddr{} 24 case TextValuer: 25 return encodePlanMacAddrCodecTextValuer{} 26 27 } 28 case TextFormatCode: 29 switch value.(type) { 30 case net.HardwareAddr: 31 return encodePlanMacaddrCodecTextHardwareAddr{} 32 case TextValuer: 33 return encodePlanTextCodecTextValuer{} 34 } 35 } 36 37 return nil 38 } 39 40 type encodePlanMacaddrCodecBinaryHardwareAddr struct{} 41 42 func (encodePlanMacaddrCodecBinaryHardwareAddr) Encode(value any, buf []byte) (newBuf []byte, err error) { 43 addr := value.(net.HardwareAddr) 44 if addr == nil { 45 return nil, nil 46 } 47 48 return append(buf, addr...), nil 49 } 50 51 type encodePlanMacAddrCodecTextValuer struct{} 52 53 func (encodePlanMacAddrCodecTextValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { 54 t, err := value.(TextValuer).TextValue() 55 if err != nil { 56 return nil, err 57 } 58 if !t.Valid { 59 return nil, nil 60 } 61 62 addr, err := net.ParseMAC(t.String) 63 if err != nil { 64 return nil, err 65 } 66 67 return append(buf, addr...), nil 68 } 69 70 type encodePlanMacaddrCodecTextHardwareAddr struct{} 71 72 func (encodePlanMacaddrCodecTextHardwareAddr) Encode(value any, buf []byte) (newBuf []byte, err error) { 73 addr := value.(net.HardwareAddr) 74 if addr == nil { 75 return nil, nil 76 } 77 78 return append(buf, addr.String()...), nil 79 } 80 81 func (MacaddrCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { 82 switch format { 83 case BinaryFormatCode: 84 switch target.(type) { 85 case *net.HardwareAddr: 86 return scanPlanBinaryMacaddrToHardwareAddr{} 87 case TextScanner: 88 return scanPlanBinaryMacaddrToTextScanner{} 89 } 90 case TextFormatCode: 91 switch target.(type) { 92 case *net.HardwareAddr: 93 return scanPlanTextMacaddrToHardwareAddr{} 94 case TextScanner: 95 return scanPlanTextAnyToTextScanner{} 96 } 97 } 98 99 return nil 100 } 101 102 type scanPlanBinaryMacaddrToHardwareAddr struct{} 103 104 func (scanPlanBinaryMacaddrToHardwareAddr) Scan(src []byte, dst any) error { 105 dstBuf := dst.(*net.HardwareAddr) 106 if src == nil { 107 *dstBuf = nil 108 return nil 109 } 110 111 *dstBuf = make([]byte, len(src)) 112 copy(*dstBuf, src) 113 return nil 114 } 115 116 type scanPlanBinaryMacaddrToTextScanner struct{} 117 118 func (scanPlanBinaryMacaddrToTextScanner) Scan(src []byte, dst any) error { 119 scanner := (dst).(TextScanner) 120 if src == nil { 121 return scanner.ScanText(Text{}) 122 } 123 124 return scanner.ScanText(Text{String: net.HardwareAddr(src).String(), Valid: true}) 125 } 126 127 type scanPlanTextMacaddrToHardwareAddr struct{} 128 129 func (scanPlanTextMacaddrToHardwareAddr) Scan(src []byte, dst any) error { 130 p := dst.(*net.HardwareAddr) 131 132 if src == nil { 133 *p = nil 134 return nil 135 } 136 137 addr, err := net.ParseMAC(string(src)) 138 if err != nil { 139 return err 140 } 141 142 *p = addr 143 144 return nil 145 } 146 147 func (c MacaddrCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { 148 return codecDecodeToTextFormat(c, m, oid, format, src) 149 } 150 151 func (c MacaddrCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { 152 if src == nil { 153 return nil, nil 154 } 155 156 var addr net.HardwareAddr 157 err := codecScan(c, m, oid, format, src, &addr) 158 if err != nil { 159 return nil, err 160 } 161 return addr, nil 162 }