Description
I'm defining an enum field whose values do not produce valid Go identifiers by default (the values are "+"
, "~"
, and "-"
), so to get around this (which was wor
79CE
king in v0.9.1) I've created a custom Go type (HistoryType
) so that the enum value variables are defined manually and have valid identifiers ("Create", "Update", "Delete").
In v0.9.1, ent did not attempt to create enum value variables for this field since I've defined the custom Go type. In v0.11.1 (and v0.10.1), however, ent seems to be attempting to do so and panics with the error message:
entc/gen: create type UserHistory: enum "+" does not have a valid Go identifier ("HistoryType+")
- The issue is present in the latest release.
- I have searched the issues of this repository and believe that this is not a duplicate.
Current Behavior 😯
Currently, running entc/gen
results in trying to generate enum value variables (or at least validating the names unnecessarily) and exits with a panic indicating that the generated variable name for the enum value is not a valid identifier.
Expected Behavior 🤔
Expected ent to not attempt to generate or validate the default generated variable names for this custom enum field and instead use the type I've defined and referenced with the GoType
method on the field in the schema.
Steps to Reproduce 🕹
Steps:
- Set up a new project (module name:
example.com/example
). - Create a model (
UserHistory
). - Define a custom type to use for the enum field on the model.
- Add an enum field to the model using the defined Go type.
- Run
go generate
.
UserHistory
schema:
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
"example.com/example/ent/history"
)
// UserHistory holds the schema definition for the User entity.
type UserHistory struct {
ent.Schema
}
// Fields of the UserHistory.
func (UserHistory) Fields() []ent.Field {
return []ent.Field{
field.String("username"),
field.Enum("history_type").GoType(history.HistoryType("")),
}
}
// Edges of the UserHistory.
func (UserHistory) Edges() []ent.Edge {
return nil
}
HistoryType
definition (in ent/history/history_type.go
):
package history
import (
"fmt"
"io"
"strconv"
)
type HistoryType string
const (
HistoryTypeCreate HistoryType = "+"
HistoryTypeUpdate HistoryType = "~"
HistoryTypeDelete HistoryType = "-"
)
func (t HistoryType) String() string {
return string(t)
}
func (HistoryType) Values() []string {
return []string{
HistoryTypeCreate.String(),
HistoryTypeUpdate.String(),
HistoryTypeDelete.String(),
}
}
// HistoryTypeValidator is a validator for the "history_type" field enum values. It is called by the builders before save.
func HistoryTypeValidator(t HistoryType) error {
switch t {
case HistoryTypeCreate, HistoryTypeUpdate, HistoryTypeDelete:
return nil
default:
return fmt.Errorf("user: invalid enum value for history_type field: %q", t)
}
}
// MarshalGQL implements graphql.Marshaler interface.
func (t HistoryType) MarshalGQL(w io.Writer) {
io.WriteString(w, strconv.Quote(t.String()))
}
// UnmarshalGQL implements graphql.Unmarshaler interface.
func (t *HistoryType) UnmarshalGQL(val interface{}) error {
str, ok := val.(string)
if !ok {
return fmt.Errorf("enum %T must be a string", val)
}
*t = HistoryType(str)
if err := HistoryTypeValidator(*t); err != nil {
return fmt.Errorf("%s is not a valid Status", str)
}
return nil
}
Your Environment 🌎
Tech | Version |
---|---|
Go | 1.17 |
Ent | 0.11.1 |
Database | PostgresQL |
Driver | https://github.com/lib/pq |