github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/courier/enumeration/gen/enum.go (about) 1 package gen 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "strconv" 8 9 "github.com/artisanhe/tools/codegen" 10 "github.com/artisanhe/tools/courier/enumeration" 11 "github.com/artisanhe/tools/courier/swagger/gen" 12 ) 13 14 func NewEnum(importPath, pkgName, name string, options gen.Enum, hasOffset bool) *Enum { 15 return &Enum{ 16 HasOffset: hasOffset, 17 Name: name, 18 ImportPath: importPath, 19 PkgName: pkgName, 20 Options: options, 21 Importer: &codegen.Importer{ 22 Local: importPath, 23 }, 24 } 25 } 26 27 type Enum struct { 28 ImportPath string 29 PkgName string 30 Name string 31 Options gen.Enum 32 Importer *codegen.Importer 33 HasOffset bool 34 } 35 36 func (m *Enum) ConstPrefix() string { 37 return codegen.ToUpperSnakeCase(m.Name) 38 } 39 40 func (m *Enum) ConstOffset() string { 41 return m.ConstPrefix() + "_OFFSET" 42 } 43 44 func (m *Enum) ConstUnknown() string { 45 return m.ConstPrefix() + "_UNKNOWN" 46 } 47 48 func (m *Enum) InvalidError() string { 49 return fmt.Sprintf("Invalid%s", m.Name) 50 } 51 52 func (m *Enum) ConstKey(key interface{}) string { 53 return fmt.Sprintf("%s__%v", m.ConstPrefix(), key) 54 } 55 56 func (m *Enum) WriteAll(w io.Writer) { 57 m.WriteVars(w) 58 m.WriteInitFunc(w) 59 m.WriteParseXFromString(w) 60 m.WriteParseXFromLabelString(w) 61 m.WriteEnumDescriptor(w) 62 m.WriteStringer(w) 63 m.WriteLabeler(w) 64 m.WriteTextMarshalerAndUnmarshaler(w) 65 m.WriteScannerAndValuer(w) 66 } 67 68 func (m *Enum) String() string { 69 buf := &bytes.Buffer{} 70 71 m.WriteAll(buf) 72 73 return fmt.Sprintf(` 74 package %s 75 76 %s 77 78 %s 79 `, 80 m.PkgName, 81 m.Importer.String(), 82 buf.String(), 83 ) 84 } 85 86 func (m *Enum) WriteVars(writer io.Writer) { 87 io.WriteString(writer, ` 88 var `+m.InvalidError()+` = errors.New("invalid `+m.Name+`") 89 `) 90 } 91 92 func (m *Enum) WriteInitFunc(w io.Writer) { 93 io.WriteString(w, ` 94 func init () { 95 `+m.Importer.Use("github.com/artisanhe/tools/courier/enumeration.RegisterEnums")+`("`+m.Name+`", map[string]string{ 96 `) 97 98 for _, option := range enumeration.Enum(m.Options) { 99 io.WriteString(w, strconv.Quote(fmt.Sprintf("%v", option.Value))+":"+strconv.Quote(option.Label)+`, 100 `) 101 } 102 103 io.WriteString(w, ` 104 }) 105 } 106 `) 107 } 108 109 func (m *Enum) WriteParseXFromString(w io.Writer) { 110 io.WriteString(w, ` 111 func `+fmt.Sprintf("Parse%sFromString", m.Name)+`(s string) (`+m.Name+`, error) { 112 switch s {`) 113 114 io.WriteString(w, ` 115 case `+strconv.Quote("")+`: 116 return `+m.ConstUnknown()+`, nil`) 117 118 for _, option := range m.Options { 119 io.WriteString(w, ` 120 case `+fmt.Sprintf(`"%v"`, option.Value)+`: 121 return `+m.ConstKey(option.Value)+`, nil`) 122 } 123 124 io.WriteString(w, ` 125 } 126 return `+m.ConstUnknown()+`, `+m.InvalidError()+` 127 } 128 `) 129 } 130 131 func (m *Enum) WriteParseXFromLabelString(w io.Writer) { 132 io.WriteString(w, ` 133 func `+fmt.Sprintf("Parse%sFromLabelString", m.Name)+`(s string) (`+m.Name+`, error) { 134 switch s {`) 135 136 io.WriteString(w, ` 137 case `+strconv.Quote("")+`: 138 return `+m.ConstUnknown()+`, nil`) 139 140 for _, option := range m.Options { 141 io.WriteString(w, ` 142 case `+strconv.Quote(option.Label)+`: 143 return `+m.ConstKey(option.Value)+`, nil`) 144 } 145 146 io.WriteString(w, ` 147 } 148 return `+m.ConstUnknown()+`,`+m.InvalidError()+` 149 } 150 `) 151 } 152 153 func (m *Enum) WriteStringer(w io.Writer) { 154 io.WriteString(w, ` 155 func (v `+m.Name+`) String() string { 156 switch v {`) 157 158 io.WriteString(w, ` 159 case `+m.ConstUnknown()+`: 160 return ""`) 161 162 for _, option := range m.Options { 163 io.WriteString(w, ` 164 case `+m.ConstKey(option.Value)+`: 165 return `+fmt.Sprintf(`"%v"`, option.Value)) 166 } 167 168 io.WriteString(w, ` 169 } 170 return "UNKNOWN" 171 } 172 `) 173 } 174 175 func (m *Enum) WriteLabeler(w io.Writer) { 176 io.WriteString(w, ` 177 func (v `+m.Name+`) Label() string { 178 switch v {`) 179 180 io.WriteString(w, ` 181 case `+m.ConstUnknown()+`: 182 return ""`) 183 184 for _, option := range m.Options { 185 io.WriteString(w, ` 186 case `+m.ConstKey(option.Value)+`: 187 return `+strconv.Quote(option.Label)) 188 } 189 190 io.WriteString(w, ` 191 } 192 return "UNKNOWN" 193 } 194 `) 195 } 196 197 func (m *Enum) WriteEnumDescriptor(w io.Writer) { 198 io.WriteString(w, ` 199 func (`+m.Name+`) EnumType() string { 200 return "`+m.Name+`" 201 } 202 203 func (`+m.Name+`) Enums() map[int][]string { 204 return map[int][]string{ 205 `) 206 207 for _, option := range m.Options { 208 if m.HasOffset { 209 io.WriteString(w, fmt.Sprintf(`int(%s) + int(%s): {%s, %s}, 210 `, m.ConstKey(option.Value), m.ConstOffset(), strconv.Quote(option.Value.(string)), strconv.Quote(option.Label))) 211 } else { 212 io.WriteString(w, fmt.Sprintf(`int(%s): {%s, %s}, 213 `, m.ConstKey(option.Value), strconv.Quote(option.Value.(string)), strconv.Quote(option.Label))) 214 } 215 } 216 217 io.WriteString(w, ` 218 } 219 }`) 220 } 221 222 func (m *Enum) WriteTextMarshalerAndUnmarshaler(w io.Writer) { 223 io.WriteString(w, ` 224 var _ interface { 225 encoding.TextMarshaler 226 encoding.TextUnmarshaler 227 } = (*`+m.Name+`)(nil) 228 229 func (v `+m.Name+`) MarshalText() ([]byte, error) { 230 str := v.String() 231 if str == "UNKNOWN" { 232 return nil, `+m.InvalidError()+` 233 } 234 return []byte(str), nil 235 } 236 237 func (v *`+m.Name+`) UnmarshalText(data []byte) (err error) { 238 *v, err = Parse`+m.Name+`FromString(string(bytes.ToUpper(data))) 239 return 240 }`) 241 } 242 243 func (m *Enum) WriteScannerAndValuer(w io.Writer) { 244 if !m.HasOffset { 245 return 246 } 247 248 io.WriteString(w, ` 249 var _ interface { 250 sql.Scanner 251 driver.Valuer 252 } = (*`+m.Name+`)(nil) 253 254 func (v *`+m.Name+`) Scan(src interface{}) error { 255 integer, err := `+m.Importer.Use("github.com/artisanhe/tools/courier/enumeration.AsInt64")+`(src, `+m.ConstOffset()+`) 256 if err != nil { 257 return err 258 } 259 *v = `+m.Name+`(integer - `+m.ConstOffset()+`) 260 return nil 261 } 262 263 func (v `+m.Name+`) Value() (driver.Value, error) { 264 return int64(v) + `+m.ConstOffset()+`, nil 265 } 266 `) 267 }