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  }