{{- define "header"}} // Code generated by go-enum DO NOT EDIT. // Version: {{ .version }} // Revision: {{ .revision }} // Build Date: {{ .buildDate }} // Built By: {{ .builtBy }} {{ range $idx, $tag := .buildTags }} //go:build {{$tag}} // +build {{$tag}} {{- end }} package {{.package}} import ( "fmt" ) {{end -}} {{- define "enum"}} const ( {{- $enumName := .enum.Name -}} {{- $enumType := .enum.Type -}} {{- $noComments := .nocomments -}} {{- $vars := dict "lastoffset" "0" -}} {{ range $rIndex, $value := .enum.Values }} {{- $lastOffset := pluck "lastoffset" $vars | first }}{{ $offset := offset $rIndex $enumType $value }} {{- if $noComments }}{{else}} {{ if eq $value.Name "_"}}// Skipped value.{{else}}// {{$value.PrefixedName}} is a {{$enumName}} of type {{$value.Name}}.{{end}}{{end}} {{- if $value.Comment}} // {{$value.Comment}} {{- end}} {{$value.PrefixedName}} {{ if eq $rIndex 0 }}{{$enumName}} = iota{{ if ne "0" $offset }} + {{ $offset }}{{end}}{{else if ne $lastOffset $offset }}{{$enumName}} = iota + {{ $offset }}{{end}}{{$_ := set $vars "lastoffset" $offset}} {{- end}} ) {{if .names -}} var ErrInvalid{{.enum.Name}} = fmt.Errorf("not a valid {{.enum.Name}}, try [%s]", strings.Join(_{{.enum.Name}}Names, ", ")) {{- else -}} var ErrInvalid{{.enum.Name}} = errors.New("not a valid {{.enum.Name}}") {{- end}} {{ template "stringer" . }} var _{{.enum.Name}}Map = {{ mapify .enum }} // String implements the Stringer interface. func (x {{.enum.Name}}) String() string { if str, ok := _{{.enum.Name}}Map[x]; ok { return str } return fmt.Sprintf("{{.enum.Name}}(%d)", x) } // IsValid provides a quick way to determine if the typed value is // part of the allowed enumerated values func (x {{.enum.Name}}) IsValid() bool { _, ok := _{{.enum.Name}}Map[x] return ok } var _{{.enum.Name}}Value = {{ unmapify .enum .lowercase }} // Parse{{.enum.Name}} attempts to convert a string to a {{.enum.Name}}. func Parse{{.enum.Name}}(name string) ({{.enum.Name}}, error) { if x, ok := _{{.enum.Name}}Value[name]; ok { return x, nil }{{if .nocase }} // Case insensitive parse, do a separate lookup to prevent unnecessary cost of lowercasing a string if we don't need to. if x, ok := _{{.enum.Name}}Value[strings.ToLower(name)]; ok { return x, nil }{{- end}} return {{.enum.Name}}(0), fmt.Errorf("%s is %w", name, ErrInvalid{{.enum.Name}}) } {{ if .mustparse }} // MustParse{{.enum.Name}} converts a string to a {{.enum.Name}}, and panics if is not valid. func MustParse{{.enum.Name}}(name string) {{.enum.Name}} { val, err := Parse{{.enum.Name}}(name) if err != nil { panic(err) } return val } {{end}} {{ if .ptr }} func (x {{.enum.Name}}) Ptr() *{{.enum.Name}} { return &x } {{end}} {{ if .marshal }} // MarshalText implements the text marshaller method. func (x {{.enum.Name}}) MarshalText() ([]byte, error) { return []byte(x.String()), nil } // UnmarshalText implements the text unmarshaller method. func (x *{{.enum.Name}}) UnmarshalText(text []byte) error { name := string(text) tmp, err := Parse{{.enum.Name}}(name) if err != nil { return err } *x = tmp return nil } {{end}} {{ if or .sql .sqlnullint .sqlnullstr}} var err{{.enum.Name}}NilPtr = errors.New("value pointer is nil") // one per type for package clashes // Scan implements the Scanner interface. func (x *{{.enum.Name}}) Scan(value interface{}) (err error) { if value == nil { *x = {{.enum.Name}}(0) return } // A wider range of scannable types. // driver.Value values at the top of the list for expediency switch v := value.(type) { case int64: *x = {{.enum.Name}}(v) case string: *x, err = Parse{{.enum.Name}}(v){{if .sqlnullint }} if err != nil { // try parsing the integer value as a string if val, verr := strconv.Atoi(v); verr == nil { *x, err = {{.enum.Name}}(val), nil } }{{end}} case []byte: *x, err = Parse{{.enum.Name}}(string(v)){{if .sqlnullint }} if err != nil { // try parsing the integer value as a string if val, verr := strconv.Atoi(string(v)); verr == nil { *x, err = {{.enum.Name}}(val), nil } }{{end}} case {{.enum.Name}}: *x = v case int: *x = {{.enum.Name}}(v) case *{{.enum.Name}}: if v == nil{ return err{{.enum.Name}}NilPtr } *x = *v case uint: *x = {{.enum.Name}}(v) case uint64: *x = {{.enum.Name}}(v) case *int: if v == nil{ return err{{.enum.Name}}NilPtr } *x = {{.enum.Name}}(*v) case *int64: if v == nil{ return err{{.enum.Name}}NilPtr } *x = {{.enum.Name}}(*v) case float64: // json marshals everything as a float64 if it's a number *x = {{.enum.Name}}(v) case *float64: // json marshals everything as a float64 if it's a number if v == nil{ return err{{.enum.Name}}NilPtr } *x = {{.enum.Name}}(*v) case *uint: if v == nil{ return err{{.enum.Name}}NilPtr } *x = {{.enum.Name}}(*v) case *uint64: if v == nil{ return err{{.enum.Name}}NilPtr } *x = {{.enum.Name}}(*v) case *string: if v == nil{ return err{{.enum.Name}}NilPtr } *x, err = Parse{{.enum.Name}}(*v){{if .sqlnullint }} if err != nil { // try parsing the integer value as a string if val, verr := strconv.Atoi(*v); verr == nil { *x, err = {{.enum.Name}}(val), nil } }{{end}} } return } {{ if or .sql .sqlnullstr }} // Value implements the driver Valuer interface. func (x {{.enum.Name}}) Value() (driver.Value, error) { {{- if eq .enum.Type "int" "int8" "int16" "int32" "int64" "uint" "uint8" "uint16" "uint32" "uint64" }} return int64(x), nil {{- else }} return {{.enum.Type }}(x), nil {{- end }} } {{ else }} // Value implements the driver Valuer interface. func (x {{.enum.Name}}) Value() (driver.Value, error) { return int64(x), nil } {{end}} {{end}} {{ if .flag }} // Set implements the Golang flag.Value interface func. func (x *{{.enum.Name}}) Set(val string) error { v, err := Parse{{.enum.Name}}(val) *x = v return err } // Get implements the Golang flag.Getter interface func. func (x *{{.enum.Name}}) Get() interface{} { return *x } // Type implements the github.com/spf13/pFlag Value interface. func (x *{{.enum.Name}}) Type() string { return "{{.enum.Name}}" } {{end}} {{ if or .sqlnullint .sqlnullstr }} type Null{{.enum.Name}} struct{ {{.enum.Name}} {{.enum.Name}} Valid bool{{/* Add some info as to whether this value was set during unmarshalling or not */}}{{if .marshal }} Set bool{{ end }} } func NewNull{{.enum.Name}}(val interface{}) (x Null{{.enum.Name}}) { x.Scan(val) // yes, we ignore this error, it will just be an invalid value. return } // Scan implements the Scanner interface. func (x *Null{{.enum.Name}}) Scan(value interface{}) (err error) { {{- if .marshal }}x.Set = true{{ end }} if value == nil { x.{{.enum.Name}}, x.Valid = {{.enum.Name}}(0), false return } err = x.{{.enum.Name}}.Scan(value) x.Valid = (err == nil) return } {{ if .sqlnullint }} // Value implements the driver Valuer interface. func (x Null{{.enum.Name}}) Value() (driver.Value, error) { if !x.Valid{ return nil, nil } // driver.Value accepts int64 for int values. return int64(x.{{.enum.Name}}), nil } {{ else }} // Value implements the driver Valuer interface. func (x Null{{.enum.Name}}) Value() (driver.Value, error) { if !x.Valid{ return nil, nil } return x.{{.enum.Name}}.String(), nil } {{ end }} {{ if .marshal }} // MarshalJSON correctly serializes a Null{{.enum.Name}} to JSON. func (n Null{{.enum.Name}}) MarshalJSON() ([]byte, error) { const nullStr = "null" if n.Valid { return json.Marshal(n.{{.enum.Name}}) } return []byte(nullStr), nil } // UnmarshalJSON correctly deserializes a Null{{.enum.Name}} from JSON. func (n *Null{{.enum.Name}}) UnmarshalJSON(b []byte) error { n.Set = true var x interface{} err := json.Unmarshal(b, &x) if err != nil{ return err } err = n.Scan(x) return err } {{ end }} {{ end }} {{ if and .sqlnullint .sqlnullstr }} type Null{{.enum.Name}}Str struct { Null{{.enum.Name}} } func NewNull{{.enum.Name}}Str(val interface{}) (x Null{{.enum.Name}}Str) { x.Scan(val) // yes, we ignore this error, it will just be an invalid value. return } // Value implements the driver Valuer interface. func (x Null{{.enum.Name}}Str) Value() (driver.Value, error) { if !x.Valid{ return nil, nil } return x.{{.enum.Name}}.String(), nil } {{ if .marshal }} // MarshalJSON correctly serializes a Null{{.enum.Name}} to JSON. func (n Null{{.enum.Name}}Str) MarshalJSON() ([]byte, error) { const nullStr = "null" if n.Valid { return json.Marshal(n.{{.enum.Name}}) } return []byte(nullStr), nil } // UnmarshalJSON correctly deserializes a Null{{.enum.Name}} from JSON. func (n *Null{{.enum.Name}}Str) UnmarshalJSON(b []byte) error { n.Set = true var x interface{} err := json.Unmarshal(b, &x) if err != nil{ return err } err = n.Scan(x) return err } {{ end }} {{ end }} {{end}} {{- define "stringer"}} const _{{.enum.Name}}Name = "{{ stringify .enum .forcelower }}" {{ if .names }}var _{{.enum.Name}}Names = {{namify .enum}} // {{.enum.Name}}Names returns a list of possible string values of {{.enum.Name}}. func {{.enum.Name}}Names() []string { tmp := make([]string, len(_{{.enum.Name}}Names)) copy(tmp, _{{.enum.Name}}Names) return tmp } {{ end -}} {{ if .values }} // {{.enum.Name}}Values returns a list of the values for {{.enum.Name}} func {{.enum.Name}}Values() []{{.enum.Name}} { return []{{.enum.Name}}{ {{ range $rIndex, $value := .enum.Values }}{{ if ne $value.Name "_"}} {{$value.PrefixedName}},{{ end }} {{- end}} } } {{ end -}} {{end}}