github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/courier/enumeration/gen/enum.go (about) 1 package gen 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "strconv" 8 9 "github.com/johnnyeven/libtools/codegen" 10 "github.com/johnnyeven/libtools/courier/enumeration" 11 "github.com/johnnyeven/libtools/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/johnnyeven/libtools/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 io.WriteString(w, fmt.Sprintf(`int(%s): {%s, %s}, 209 `, m.ConstKey(option.Value), strconv.Quote(fmt.Sprintf("%s", option.Value)), strconv.Quote(option.Label))) 210 } 211 212 io.WriteString(w, ` 213 } 214 }`) 215 } 216 217 func (m *Enum) WriteTextMarshalerAndUnmarshaler(w io.Writer) { 218 io.WriteString(w, ` 219 var _ interface { 220 encoding.TextMarshaler 221 encoding.TextUnmarshaler 222 } = (*`+m.Name+`)(nil) 223 224 func (v `+m.Name+`) MarshalText() ([]byte, error) { 225 str := v.String() 226 if str == "UNKNOWN" { 227 return nil, `+m.InvalidError()+` 228 } 229 return []byte(str), nil 230 } 231 232 func (v *`+m.Name+`) UnmarshalText(data []byte) (err error) { 233 *v, err = Parse`+m.Name+`FromString(string(bytes.ToUpper(data))) 234 return 235 }`) 236 } 237 238 func (m *Enum) WriteScannerAndValuer(w io.Writer) { 239 if !m.HasOffset { 240 return 241 } 242 243 io.WriteString(w, ` 244 var _ interface { 245 sql.Scanner 246 driver.Valuer 247 } = (*`+m.Name+`)(nil) 248 249 func (v *`+m.Name+`) Scan(src interface{}) error { 250 integer, err := `+m.Importer.Use("github.com/johnnyeven/libtools/courier/enumeration.AsInt64")+`(src, `+m.ConstOffset()+`) 251 if err != nil { 252 return err 253 } 254 *v = `+m.Name+`(integer - `+m.ConstOffset()+`) 255 return nil 256 } 257 258 func (v `+m.Name+`) Value() (driver.Value, error) { 259 return int64(v) + `+m.ConstOffset()+`, nil 260 } 261 `) 262 }