personal-site/ent/admin/extension.go
2025-04-20 11:16:18 -04:00

97 lines
1.8 KiB
Go

package admin
import (
"embed"
"strings"
"text/template"
"unicode"
"entgo.io/ent/entc"
"entgo.io/ent/entc/gen"
"entgo.io/ent/schema/field"
)
var (
//go:embed templates
templateDir embed.FS
)
// Extension is the Ent extension that generates code to support the entity admin panel.
type Extension struct {
entc.DefaultExtension
}
func (*Extension) Templates() []*gen.Template {
return []*gen.Template{
gen.MustParse(
gen.NewTemplate("admin").
Funcs(template.FuncMap{
"fieldName": fieldName,
"fieldLabel": FieldLabel,
"fieldIsPointer": fieldIsPointer,
}).
ParseFS(templateDir, "templates/*tmpl"),
),
}
}
// fieldName provides a struct field name from an entity field name (ie, user_id -> UserID).
func fieldName(name string) string {
if len(name) == 0 {
return name
}
parts := strings.Split(name, "_")
for i := 0; i < len(parts); i++ {
if parts[i] == "id" {
parts[i] = "ID"
} else {
parts[i] = upperFirst(parts[i])
}
}
return strings.Join(parts, "")
}
// FieldLabel provides a label for an entity field name (ie, user_id -> User ID).
func FieldLabel(name string) string {
if len(name) == 0 {
return name
}
parts := strings.Split(name, "_")
for i := 0; i < len(parts); i++ {
if parts[i] == "id" {
parts[i] = "ID"
}
if i == 0 {
parts[i] = upperFirst(parts[i])
}
}
return strings.Join(parts, " ")
}
// fieldIsPointer determines if a given entity field should be a pointer on the struct.
func fieldIsPointer(f *gen.Field) bool {
switch {
case f.Type.Type == field.TypeBool:
return false
case f.Optional,
f.Default,
f.Sensitive(),
f.Nillable:
return true
}
return false
}
// upperFirst uppercases the first character of a given string.
func upperFirst(s string) string {
if len(s) == 0 {
return s
}
out := []rune(s)
out[0] = unicode.ToUpper(out[0])
return string(out)
}