go-lemmy/cmd/gen/generator/struct.go

124 lines
2.5 KiB
Go
Raw Permalink Normal View History

package generator
import (
"io"
"strings"
"unicode"
"github.com/dave/jennifer/jen"
"go.elara.ws/go-lemmy/cmd/gen/extractor"
)
type StructGenerator struct {
w io.Writer
PkgName string
}
func NewStruct(w io.Writer, pkgName string) *StructGenerator {
return &StructGenerator{w, pkgName}
}
func (s *StructGenerator) Generate(items []extractor.Struct) error {
f := jen.NewFile(s.PkgName)
2023-04-21 02:27:38 +00:00
f.HeaderComment("Code generated by go.elara.ws/go-lemmy/cmd/gen (struct generator). DO NOT EDIT.")
for _, item := range items {
if len(item.UnionNames) > 0 {
f.Type().Id(item.Name).String()
f.Const().DefsFunc(func(g *jen.Group) {
for _, member := range item.UnionNames {
constName := strings.Replace(item.Name+string(member), " ", "", -1)
g.Id(constName).Id(item.Name).Op("=").Lit(string(member))
}
})
} else {
f.Type().Id(item.Name).StructFunc(func(g *jen.Group) {
for _, field := range item.Fields {
2023-10-04 23:16:36 +00:00
g.Id(transformFieldName(field.Name)).Add(getType(field)).Tag(map[string]string{
"json": field.Name,
"url": field.Name + ",omitempty",
})
}
if strings.HasSuffix(item.Name, "Response") {
2023-10-05 03:45:36 +00:00
g.Id("Error").Id("Optional").Types(jen.String()).Tag(map[string]string{"json": "error"})
}
})
}
}
return f.Render(s.w)
}
2023-10-04 23:16:36 +00:00
func getType(f extractor.Field) jen.Code {
// Some time fields are strings in the JS client,
// use time.Time for those
switch f.Name {
case "published", "updated", "when_":
return jen.Qual("time", "Time")
}
// Rank types such as hot_rank and hot_rank_active may be floats.
if strings.Contains(f.Name, "rank") {
return jen.Float64()
}
2023-09-25 02:36:37 +00:00
t := transformType(f.Name, f.Type)
if f.IsArray {
t = "[]" + t
}
if f.IsOptional {
t = "Optional[" + t + "]"
}
2023-10-04 23:16:36 +00:00
return jen.Id(t)
}
2023-09-25 02:36:37 +00:00
func transformType(name, t string) string {
switch t {
case "number":
return "int64"
case "boolean":
return "bool"
default:
2023-09-25 02:36:37 +00:00
return t
}
}
func transformFieldName(s string) string {
s = snakeToCamel(s)
s = strings.NewReplacer(
"Id", "ID",
"Url", "URL",
"Nsfw", "NSFW",
"Jwt", "JWT",
"Crud", "CRUD",
2023-09-25 02:36:37 +00:00
"Pm", "PM",
"Totp", "TOTP",
"2fa", "2FA",
"Png", "PNG",
"Uuid", "UUID",
"Wav", "WAV",
).Replace(s)
return s
}
func snakeToCamel(s string) string {
sb := &strings.Builder{}
capitalizeNext := true
for _, char := range s {
if char == '_' {
capitalizeNext = true
continue
}
if capitalizeNext {
sb.WriteRune(unicode.ToUpper(char))
capitalizeNext = false
} else {
sb.WriteRune(char)
}
}
return sb.String()
}