...
1 package pgtype
2
3 import "fmt"
4
5
6
7 type EnumType struct {
8 value string
9 status Status
10
11 typeName string
12 members []string
13 membersMap map[string]string
14 }
15
16
17 func NewEnumType(typeName string, members []string) *EnumType {
18 et := &EnumType{typeName: typeName, members: members}
19 et.membersMap = make(map[string]string, len(members))
20 for _, m := range members {
21 et.membersMap[m] = m
22 }
23 return et
24 }
25
26 func (et *EnumType) NewTypeValue() Value {
27 return &EnumType{
28 value: et.value,
29 status: et.status,
30
31 typeName: et.typeName,
32 members: et.members,
33 membersMap: et.membersMap,
34 }
35 }
36
37 func (et *EnumType) TypeName() string {
38 return et.typeName
39 }
40
41 func (et *EnumType) Members() []string {
42 return et.members
43 }
44
45
46
47 func (dst *EnumType) Set(src interface{}) error {
48 if src == nil {
49 dst.status = Null
50 return nil
51 }
52
53 if value, ok := src.(interface{ Get() interface{} }); ok {
54 value2 := value.Get()
55 if value2 != value {
56 return dst.Set(value2)
57 }
58 }
59
60 switch value := src.(type) {
61 case string:
62 dst.value = value
63 dst.status = Present
64 case *string:
65 if value == nil {
66 dst.status = Null
67 } else {
68 dst.value = *value
69 dst.status = Present
70 }
71 case []byte:
72 if value == nil {
73 dst.status = Null
74 } else {
75 dst.value = string(value)
76 dst.status = Present
77 }
78 default:
79 if originalSrc, ok := underlyingStringType(src); ok {
80 return dst.Set(originalSrc)
81 }
82 return fmt.Errorf("cannot convert %v to enum %s", value, dst.typeName)
83 }
84
85 return nil
86 }
87
88 func (dst EnumType) Get() interface{} {
89 switch dst.status {
90 case Present:
91 return dst.value
92 case Null:
93 return nil
94 default:
95 return dst.status
96 }
97 }
98
99 func (src *EnumType) AssignTo(dst interface{}) error {
100 switch src.status {
101 case Present:
102 switch v := dst.(type) {
103 case *string:
104 *v = src.value
105 return nil
106 case *[]byte:
107 *v = make([]byte, len(src.value))
108 copy(*v, src.value)
109 return nil
110 default:
111 if nextDst, retry := GetAssignToDstType(dst); retry {
112 return src.AssignTo(nextDst)
113 }
114 return fmt.Errorf("unable to assign to %T", dst)
115 }
116 case Null:
117 return NullAssignTo(dst)
118 }
119
120 return fmt.Errorf("cannot decode %#v into %T", src, dst)
121 }
122
123 func (EnumType) PreferredResultFormat() int16 {
124 return TextFormatCode
125 }
126
127 func (dst *EnumType) DecodeText(ci *ConnInfo, src []byte) error {
128 if src == nil {
129 dst.status = Null
130 return nil
131 }
132
133
134 if s, found := dst.membersMap[string(src)]; found {
135 dst.value = s
136 } else {
137
138
139
140 dst.value = string(src)
141 }
142 dst.status = Present
143
144 return nil
145 }
146
147 func (dst *EnumType) DecodeBinary(ci *ConnInfo, src []byte) error {
148 return dst.DecodeText(ci, src)
149 }
150
151 func (EnumType) PreferredParamFormat() int16 {
152 return TextFormatCode
153 }
154
155 func (src EnumType) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
156 switch src.status {
157 case Null:
158 return nil, nil
159 case Undefined:
160 return nil, errUndefined
161 }
162
163 return append(buf, src.value...), nil
164 }
165
166 func (src EnumType) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
167 return src.EncodeText(ci, buf)
168 }
169
View as plain text