alvaroloes / enumer Goto Github PK
View Code? Open in Web Editor NEWA Go tool to auto generate methods for your enums
License: Other
A Go tool to auto generate methods for your enums
License: Other
Hi!
I would like to suggest using Semantic Versioning for enumer's releases.
What do you think about it?
Thanks.
Go 1.19 changed how the go tool handles doc comments. This leads to gofmt
now reformatting enumer-generated files from previous versions like this:
// Code generated by "enumer -type ObservationID"; DO NOT EDIT.
+ //
package easee
I want to generate an Enumer like this:
{
=
=~
!=
!~
}
Hi
Do you mind adding a license? Preferably something similar to GO's license?
Thanks.
Hi Alvaro! I have a use case where I'm trying to model enum types from other systems. Some of these already use snake_case which is great because you've already included that transform here. However one or two of these models use strings which are whitespace separated. Would you agree that that transformer could be added to this library? Thanks so much!
I have an enum like
type Fruit byte
const (
APPLE Fruit = iota
PEAR
)
when serialising a value APPLE
to json I would expect the value to appear in the output json. However, the value does not appear, presumably because it is 0
under the hood
Replacing Fruit = iota
with Fruit = iota + 1
means APPLE gets outputted as expected
I'm new to Go from java, so there may be good reason why this is so, but it was surprising for me, so, if you don't think it should be fixed, perhaps it's worth a mention in the documentation
Hi. I'm using
type Action int
const (
ActionFoo Action = iota + 1
ActionBar
)
to make the default zero value be an undefined value. I just noticed that some JSON marshaled as
{"action": "Action(0)", ...}
I would much prefer that marshaling enums that are not a valid value produce an error. It would expose my programming errors sooner. What do you think?
Request List Function:
func (...) List() []Type {}
func (...) ListString() []string {}
Seems that there are some problems with 1.18 in conjunction with the old x/tools library:
go generate ./...
enumer: internal error: package "fmt" without types was imported from "github.com/evcc-io/evcc/charger/easee"
charger/easee/signalr.go:30: running "enumer": exit status 1
I could not track it down yet; the package in question above does not make use of generics. Code is publicly available if anyone wants to take a stab.
This is actually a duplicate of #62
When using enumer in a CI environment I encounter this issue.
enumer: moving tempfile to output file: rename /tmp/SomeType_enumer_457916248 sometype_enumer.go: invalid cross-device link
Due to how the container is sandboxed, this is not possible in my case.
In my opinion this should be a setting?
https://github.com/alvaroloes/enumer/blob/master/enumer.go#L7 shows the template for to string transformation. Reading user input from config file I would like to support this in a case-insensitive way. Since my type is in camel case, there is no option of preparing this operation on the string side before conversion.
Add support for generating encoding.TextMarshaler and encoding.TextUnmarshaler interface methods for generated types. So the generated types can be used for JSON marshaling and unmarshaling from & to strings.
Example:
func (d Day) MarshalText() ([]byte, error) {
return []byte(d.String()), nil
}
More Info: https://golang.org/pkg/encoding/
This would export the enum to json and allow other languages to use the enum.
Eg (pseudocode):
enums/myenum.go
:
//go:generate enumer -type=MyEnum -json -sql
// MyEnum:
type MyEnum int
const (
MyEnumA MyEnum = iota + 1
MyEnumB
MyEnumC
)
main.go
:
func main() {
myMap := make(map[enums.MyEnum]string)
myMap[enums.MyEnumA] = "A"
myMap[enums.MyEnumB] = "B"
jsonBytes, _ := json.MarshalIndent(HostRecommendationConfig,"", " ")
fmt.Println(string(jsonBytes))
}
The above code will print the output:
{
"1": "A",
"2": "B"
}
Expected output:
{
"A": "A",
"B": "B"
}
Ran into issues with imports running with go 1.9 - when stringer is doing the type checking step.
I think there have been some changes between 1.8->1.9 - possibly related to this...
Line 51 in d27f80a
the revision tag in your go.mod
for golang.org/x/tools
is too old. Enumer will fail with go1.14+.
update with : golang.org/x/tools v0.0.0-20200725200936-102e7d357031
thanks.
I would like to request a function which returns all the ENUMS as comma separated list.
See the following example from stackoverflow: http://stackoverflow.com/a/17203007
CREATE TABLE prices (
id INTEGER PRIMARY KEY,
pName TEXT CHECK( LENGTH(pName) <= 100 ) NOT NULL DEFAULT '',
pType TEXT CHECK( pType IN ('M','R','H') ) NOT NULL DEFAULT 'M',
pField TEXT CHECK( LENGTH(pField) <= 50 ) NULL DEFAULT NULL,
pFieldExt TEXT CHECK( LENGTH(pFieldExt) <= 50 ) NULL DEFAULT NULL,
cmp_id INTEGER NOT NULL DEFAULT '0'
)
Regards of database system, (MySQL, PostgreSQL, SQLite, Microsoft SQL Server) it is quite common to use a statement involving IN
.
I would like to do the following.
Generate a ENUM for a const with enumer, with -json, -sql. Then I would like to have a function which returns the ENUMS as a comma separated list so I can place it dynamically within SQL statements with Sprintf. This way I only have to re-generate the ENUM and the SQL statement will also include the new ENUM within either a CHECK
statement like above or as a IN
statement.
Example (ENDUSER):
func GetUser() interface{} {
return db.Exec(fmt.Sprintf(`
SELECT *
FROM USERS
WHERE
USERNAME=$1
AND
TYPE IN ('%s')`, enumer.SQLList()), username)
}
Function name for this request can be chosen better :-)
P.S. Above code is just a example.
Hi everyone. Can u help me with my problem?
enumer: checking package: report.go:4:2: could not import sync (type-checking package "sync" failed (/usr/local/go/src/sync/pool.go:9:2: could not import runtime (type-checking package "runtime" failed (/usr/local/go/src/runtime/mem_linux.go:21:6: sysAlloc redeclared in this block))))
When using enumer, it's possible to end up with something where the only places that a constant would be directly used would be in the conversion to/from string, but enumer doesn't use the constant, it uses a literal value.
See examples here:
dominikh/go-tools#660
So for instance
var _DayNameToValueMap = map[string]Day{
_DayName[0:6]: 0,
_DayName[6:13]: 1,
_DayName[13:22]: 2,
_DayName[22:30]: 3,
_DayName[30:36]: 4,
_DayName[36:44]: 5,
_DayName[44:50]: 6,
}
This could use Monday
instead of the literal 0, and then it would be easier for analysis tools to detect that the constant value is in some way used. It might also be easier to read the resulting code, although I recognize that's not especially important with generated code.
Not using modules!
enumer: checking package: loglevel_enumer.go:6:2: could not import fmt (type-checking package "fmt" failed (/golangdev/go/src/fmt/print.go:9:2: could not import internal/fmtsort (type-checking package "internal/fmtsort" failed (/golangdev/go/src/internal/fmtsort/sort.go:12:2: could not import reflect (type-checking package "reflect" failed (/golangdev/go/src/reflect/type.go:19:2: could not import runtime (type-checking package "runtime" failed /golangdev/go/src/runtime/mem_linux.go:21:6: sysAlloc redeclared in this block))))))))
.gopath~/src/github.com/influxdata/telegraf/plugins/parsers/sefofmt/loglevel.go:1: running "enumer": exit status 1
I see the same error when using stringer
, so perhaps this error is upstream.
For example:
JSON would transform to snake_case
String() would transform to kebab-case
Therefore "cs-uri-stem" would be defined as var CsUriStem
and run with a transform of kebab-case, but would marshal as cs_uri_stem
.
Seems like I cannot use any imports with enumer
. I have to uncomment all for a successful run.
The project builds fine otherwise.
enumer: checking package: main.go:5:2: could not import gopkg.in/yaml.v2 (can't find import: "foo/vendor/gopkg.in/yaml.v2")
My setup:
$ go version
go version go1.9.2 darwin/amd64
$ ls -l -d $GOPATH/src/foo/vendor/gopkg.in/yaml.v2/
drwxr-xr-x 16 tcurdt staff 544 Dec 12 03:06 .../src/foo/vendor/gopkg.in/yaml.v2/
With Go 1.11 release and go mod introduction I moved some projects that uses enumer out of $GOPATH
and so now it can't generate code when package has some imports either because of built-in dependencies failing or because it just can't find import out of $GOPATH
.
E.g. when I try to generate from this MWE:
package mwe
import (
"log"
)
type Type uint8
//go:generate enumer -type=Type -json -transform=snake
const (
ConstOne Type = iota
ConstTwo
)
func init() {
var a = ConstOne
log.Println("a", a)
}
You'll get that:
enumer: checking package: mwe.go:4:2: could not import log (type-checking package "log" failed ($GOPATH/src/log/log.go:18:2: could not import fmt (type-checking package "fmt" failed ($GOPATH/src/fmt/format.go:8:2: could not import strconv (type-checking package "strconv" failed ($GOPATH/src/strconv/atof.go:13:8: could not import math (type-checking package "math" failed ($GOPATH/src/math/exp_asm.go:9:8: could not import internal/cpu (type-checking package "internal/cpu" failed ($GOPATH/src/internal/cpu/cpu_x86.go:9:7: CacheLineSize redeclared in this block))))))))))
mwe.go:9: running "enumer": exit status 1
Since the variable name becomes the enum string, it would be nice to be able to define a Prefix or Suffix string that should be removed.
For example, while adding enums for Cloudfront log parsing.
// EdgeResultType represents a specific result type that is represented in the Logline
type EdgeResultType int
const (
// Hit means the object was served to the viewer from the edge cache.
Hit EdgeResultType = iota
// RefreshHit means the object was in the edge cache but it had expired, so CloudFront contacted the origin to verify that the cache has the latest version of the object.
RefreshHit
// Miss means the request could not be satisfied by an object in the edge cache, so CloudFront forwarded the request to the origin server and returned the result to the viewer.
Miss
// LimitExceeded means the request was denied because a CloudFront limit was exceeded.
LimitExceeded
// CapacityExceeded returns a 503 error because the edge location didn't have enough capacity at the time of the request to serve the object
CapacityExceeded
// Error means the request resulted in a client error (sc-status is 4xx) or a server error (sc-status is 5xx).
Error
// Redirect means that we redirected from HTTP to HTTPS. Alternatively, if the status is 403 and the distribution is configured CloudFront to restrict the geographic distribution of your content, the request might have come from a restricted location.
// If the value of x-edge-result-type is Error and the value of x-edge-response-result-type is not Error, the client disconnected before finishing the download.
Redirect
)
It would be useful to be able to Prefix these enums to be EdgeResultHit
, EdgeResultRefreshHit
, but keep the generated string as Hit, RefreshHit, for actual parsing.
This would be useful for us and it seems like an obvious feature. I'm happy to work on a PR if this is something you'd like to add.
Hi Álvaro,
I just started looking at enumer and it looks great for my use case. Basically I want to automatically generate strings for enums, and convert strings back to enums.
However, the strings will not always be the same as the enum name. This was solved by the stringer
tool by adding a -linecomment
flag. With this flag, the line comment after an enum will be used for the string value, instead of the name of the enum.
Please consider adding it to enumer. That would be very useful!
For an example usage of -linecomment
see https://github.com/llir/l/blob/f6ae116b371f89c51d52b496de3487149b30335a/ir/ll/enums.go#L15
//go:generate stringer -linecomment -type Linkage
// Linkage specifies the linkage of a global identifier.
type Linkage uint8
// Linkage kinds.
const (
LinkageNone Linkage = iota // none
LinkageAppending // appending
LinkageAvailableExternally // available_externally
LinkageCommon // common
LinkageInternal // internal
LinkageLinkOnce // linkonce
LinkageLinkOnceODR // linkonce_odr
LinkagePrivate // private
LinkageWeak // weak
LinkageWeakODR // weak_odr
// External linkage.
LinkageExternal // external
LinkageExternWeak // extern_weak
)
Cheers,
Robin
the x/tools package used by enumer causes it to generate the following error when it is built with go 1.22.0 on Mac OSX silicon.
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x104847480]
goroutine 169 [running]:
go/types.(*Checker).handleBailout(0x14000826000, 0x14000249c78)
/usr/local/go/src/go/types/check.go:367 +0x9c
panic({0x10492b840?, 0x104ab2c30?})
/usr/local/go/src/runtime/panic.go:770 +0x124
go/types.(*StdSizes).Sizeof(0x0, {0x1049670f8, 0x104ab5a60})
/usr/local/go/src/go/types/sizes.go:228 +0x320
go/types.(*Config).sizeof(...)
/usr/local/go/src/go/types/sizes.go:333
go/types.representableConst.func1({0x1049670f8?, 0x104ab5a60?})
/usr/local/go/src/go/types/const.go:76 +0x9c
go/types.representableConst({0x104968b98, 0x104aab660}, 0x14000826000, 0x104ab5a60, 0x0)
/usr/local/go/src/go/types/const.go:92 +0x138
go/types.(*Checker).arrayLength(0x14000826000, {0x104968730, 0x14000320180?})
/usr/local/go/src/go/types/typexpr.go:510 +0x238
module github.com/alvaroloes/enumer
go/types.(*Checker).typInternal(0x14000826000, {0x104967fe0, 0x1400031c0c0}, 0x0)
/usr/local/go/src/go/types/typexpr.go:299 +0x3bc
go/types.(*Checker).definedType(0x14000826000, {0x104967fe0, 0x1400031c0c0}, 0x14000249238?)
/usr/local/go/src/go/types/typexpr.go:180 +0x2c
go/types.(*Checker).varType(0x14000826000, {0x104967fe0, 0x1400031c0c0})
/usr/local/go/src/go/types/typexpr.go:145 +0x2c
go/types.(*Checker).structType(0x14000826000, 0x14000818270, 0x14000818270?)
/usr/local/go/src/go/types/struct.go:113 +0x128
module github.com/alvaroloes/enumer
go/types.(*Checker).typInternal(0x14000826000, {0x104968010, 0x1400031a9f0}, 0x14000822320)
/usr/local/go/src/go/types/typexpr.go:316 +0xed0
go/types.(*Checker).definedType(0x14000826000, {0x104968010, 0x1400031a9f0}, 0x1046ac1e4?)
/usr/local/go/src/go/types/typexpr.go:180 +0x2c
go/types.(*Checker).typeDecl(0x14000826000, 0x14000822320, 0x1400037c080, 0x0)
/usr/local/go/src/go/types/decl.go:615 +0x39c
go/types.(*Checker).objDecl(0x14000826000, {0x10496abb8, 0x14000822320}, 0x0)
/usr/local/go/src/go/types/decl.go:197 +0x880
go/types.(*Checker).packageObjects(0x14000826000)
/usr/local/go/src/go/types/resolver.go:681 +0x3c0
go/types.(*Checker).checkFiles(0x14000826000, {0x1400030e008, 0x1, 0x1})
/usr/local/go/src/go/types/check.go:408 +0x164
go/types.(*Checker).Files(...)
/usr/local/go/src/go/types/check.go:372
golang.org/x/tools/go/packages.(*loader).loadPackage(0x140000c22c0, 0x1400040b8a0)
/Users/johnpaulhumphrey/go/pkg/mod/golang.org/x/[email protected]/go/packages/packages.go:825 +0x4f4
golang.org/x/tools/go/packages.(*loader).loadRecursive.func1()
/Users/johnpaulhumphrey/go/pkg/mod/golang.org/x/[email protected]/go/packages/packages.go:683 +0x178
sync.(*Once).doSlow(0x0?, 0x0?)
/usr/local/go/src/sync/once.go:74 +0x100
sync.(*Once).Do(...)
/usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/packages.(*loader).loadRecursive(0x0?, 0x0?)
/Users/johnpaulhumphrey/go/pkg/mod/golang.org/x/[email protected]/go/packages/packages.go:670 +0x50
golang.org/x/tools/go/packages.(*loader).loadRecursive.func1.1(0x0?)
/Users/johnpaulhumphrey/go/pkg/mod/golang.org/x/[email protected]/go/packages/packages.go:677 +0x30
created by golang.org/x/tools/go/packages.(*loader).loadRecursive.func1 in goroutine 40
/Users/johnpaulhumphrey/go/pkg/mod/golang.org/x/[email protected]/go/packages/packages.go:676 +0x84
As you can see these errors come from x/tools not enumer
per temporalio/sdk-go#1382 we need to update x/tools in go mod to a later version
I edited enumer/go.mod to
module github.com/alvaroloes/enumer
go 1.17 // bumped to later version
require (
github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1
golang.org/x/tools v0.17.0 //was v0.0.0-20190525145741-7be61e1b0e51
)
require golang.org/x/mod v0.14.0 // indirect
$ enumer
Usage of enumer:
stringer [flags] -type T [directory]
[...]
Given the following:
type ColorType int
const (
RED ColorType = iota
GREEN
BLUE
NIL
)
I would like to set the value of NIL
to be an empty string. Is this possible?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.