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 }
163
View as plain text