-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update or replace the enumer go:generate tool #2998
Comments
This could be an easier approach, which eases maintainability and will remove the need for generators. Using a method String() for the SystemType type also satisfies the interface expected by fmt's %s verb (as you can see in the tests). // systemtag.go
package systemtag
type SystemTag uint32
const (
TagProto SystemTag = 1 << iota
TagSubproto
TagStatus
)
var tagToValue = map[SystemTag]string{
TagProto: "proto",
TagSubproto: "subproto",
TagStatus: "status",
}
func (st SystemTag) String() string {
return tagToValue[st]
} // systemtag_test.go
package systemtag
import "testing"
func TestSystemTag(t *testing.T) {
cases := []struct {
name string
tag SystemTag
expect string
}{
{
name: "TagProto = proto",
tag: TagProto,
expect: "proto",
},
}
for _, c := range cases {
if c.tag.String() != c.expect {
t.Errorf("received %s and expected %s", c.tag, c.expect)
}
}
} |
Thanks for the suggestion, @nrxr, but it's not a viable one, since it has a few significant downsides to the enumer approach:
|
I understand, yet, it seems these are very rarely updated and by tying the code to a generator you can get stuck in a situation like the current one.
Yes, is error-prone but nothing that a unit test of constant to value (as the one I wrote early on) could not catch on-time. Right now, you're trusting the output of an unmaintained generator :-)
I got interested on this, it seems there are less clever ways to implement it way more efficiently. The net/http library does something like this: And using a simple string slice instead of a string + index, you get even better results: Also, the ExecutionStatusString function can be implemented a bit faster using a map with the swapped types from what I sent before and even faster using the idiomatic way. If performance is the important bit, a combination of String() from the manual implementation with the String of the idiomatic implementation would be the ideal. This code is way cleaner than what enumer generates, in my opinion. Yet, I guess writing a generator that creates code like this using stringer as the starting point wouldn't be so hard if you would prefer the generator-way. The implementations here would be backwards-compatible with what you already have in the project: https://github.com/nrxr/enumbenchmarks |
Awesome work! 🎉 ❤️ Thanks! 🙇
Completely agree!
Yeah, I'd still probably somewhat prefer a better generator that uses this approach. It will have uses outside of k6, and we'd only need to write tests for the generator, not for the base functionality of every enum set that uses it. |
@nrxr, is such a generator an OSS project that you are interested in creating? This is a relatively |
@na-- I'm actually considering it for this weekend. I'll let you know. I got really involved with this issue now and want to see it to fruition. My expectation would be a generator that makes code that can be maintained manually too, if the generator were to fail, and yet is more performant than current options. |
Currently, we are using https://github.com/alvaroloes/enumer to semi-automatically generate some helper methods for a several
enum
types we have in k6:k6/.github/workflows/lint.yml
Line 31 in c09919b
k6/metrics/system_tag.go
Lines 12 to 13 in c09919b
k6/lib/execution.go
Lines 34 to 35 in c09919b
(and others)
Unfortunately, it hasn't been updated since 2019, and the current version produces code that has linter errors. It's also produces some methods we don't really use in all types...
The active fork of that tool seems to be https://github.com/dmarkham/enumer, and it fixes some things. Unfortunately, it also makes the second problem even worse. For example, it adds lowercase support (dmarkham/enumer#22) in a way that can't be disabled (dmarkham/enumer#40), which is not something we necessarily want in all of our types... 😞
The text was updated successfully, but these errors were encountered: