feat: allow marking values as invalid with "!" - #312
Conversation
|
Will add testing for new functionality a bit later... |
|
Why make a second map, instead o just leaving it out of the original lookup map? |
|
The original map is used in the However, I admit that the whole concept is a bit sus. My desire is to have enums that are not zero-initialized to valid values, so that there're less bugs. One way to achieve that, is to start enumeration from one instead of zero. I've realized that it's already possible: // ENUM(red=1, green, blue)However, it's also useful to have a sentinel-value (like // ENUM(unknown, red, green, blue)would generate a zero One way of doing what I want is to allow a user to mark specific values as invalid. That's what the PR is about. It is somewhat questionable, though, since it's probably not often when someone needs to have multiple invalid sentinels. It could be more reasonable to add a CLI-arg like |
|
That could be enough (I can submit a separate PR): diff --git a/generator/enum.tmpl b/generator/enum.tmpl
index 8d214a540c..c1cb894ecc 100644
--- a/generator/enum.tmpl
+++ b/generator/enum.tmpl
@@ -58,7 +58,11 @@
// IsValid provides a quick way to determine if the typed value is
// part of the allowed enumerated values
-func (x {{.enum.Name}}) IsValid() bool {
+func (x {{.enum.Name}}) IsValid() bool { {{if .invalidZero}}var zero {{.enum.Name}}
+ if x == zero {
+ return false
+ }{{end}}
+
_, ok := _{{.enum.Name}}Map[x]
return ok
}
diff --git a/generator/generator.go b/generator/generator.go
index cac315ae4c..c7269a8060 100644
--- a/generator/generator.go
+++ b/generator/generator.go
@@ -213,6 +213,7 @@
"nocase": g.CaseInsensitive,
"nocomments": g.NoComments,
"noIota": g.NoIota,
+ "invalidZero": g.InvalidZero,
"marshal": g.Marshal,
"sql": g.SQL,
"sqlint": g.SQLInt,
diff --git a/generator/options.go b/generator/options.go
index df085941b6..eb066a34cd 100644
--- a/generator/options.go
+++ b/generator/options.go
@@ -4,6 +4,7 @@
type GeneratorConfig struct {
NoPrefix bool `json:"no_prefix"`
NoIota bool `json:"no_iota"`
+ InvalidZero bool `json:"invalid_zero"`
LowercaseLookup bool `json:"lowercase_lookup"`
CaseInsensitive bool `json:"case_insensitive"`
Marshal bool `json:"marshal"`
diff --git a/main.go b/main.go
index a149bc4b3d..7a51ee7503 100644
--- a/main.go
+++ b/main.go
@@ -26,6 +26,7 @@
FileNames cli.StringSlice
NoPrefix bool
NoIota bool
+ InvalidZero bool
Lowercase bool
NoCase bool
Marshal bool
@@ -229,6 +230,11 @@
Usage: "Disables the use of iota in generated enums.",
Destination: &argv.NoIota,
},
+ &cli.BoolFlag{
+ Name: "invalid-zero",
+ Usage: "Treat zero-value as invalid.",
+ Destination: &argv.InvalidZero,
+ },
},
Action: func(ctx *cli.Context) error {
// Validate incompatible flag combinations
@@ -262,6 +268,7 @@
config := generator.GeneratorConfig{
NoPrefix: argv.NoPrefix,
NoIota: argv.NoIota,
+ InvalidZero: argv.InvalidZero,
LowercaseLookup: argv.Lowercase || argv.NoCase,
CaseInsensitive: argv.NoCase,
Marshal: argv.Marshal, |
|
The |
I see, though, that it could be reasonable to, indeed, just remove the value from the original map. If it's just a sentinel, would it be of benefit to know its name? |
|
What about just adding a const value of the invalid value right below the enum, rather than messing with the generation? Then you can use the Sentinel in code but all the enum parsing code would treat it as unknown. |
|
Wow, never occurred to me ... XD (genuinely, not sarcasm) |
Example:
Additional map is generated:
The
IsValidmethod is changed to:The exclamation mark is removed from the string-value of the enum: