2023-01-05 20:51:45 +00:00
|
|
|
package generator
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"strings"
|
2023-09-25 02:28:46 +00:00
|
|
|
"unicode"
|
2023-01-05 20:51:45 +00:00
|
|
|
|
|
|
|
"github.com/dave/jennifer/jen"
|
2023-09-25 02:28:46 +00:00
|
|
|
"go.elara.ws/go-lemmy/cmd/gen/extractor"
|
2023-01-05 20:51:45 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type StructGenerator struct {
|
|
|
|
w io.Writer
|
|
|
|
PkgName string
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewStruct(w io.Writer, pkgName string) *StructGenerator {
|
|
|
|
return &StructGenerator{w, pkgName}
|
|
|
|
}
|
|
|
|
|
2023-09-25 02:28:46 +00:00
|
|
|
func (s *StructGenerator) Generate(items []extractor.Struct) error {
|
2023-01-05 20:51:45 +00:00
|
|
|
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.")
|
2023-09-25 02:28:46 +00:00
|
|
|
|
2023-01-05 20:51:45 +00:00
|
|
|
for _, item := range items {
|
2023-09-25 02:28:46 +00:00
|
|
|
if len(item.UnionNames) > 0 {
|
|
|
|
f.Type().Id(item.Name).String()
|
2023-01-05 20:51:45 +00:00
|
|
|
|
2023-09-25 02:28:46 +00:00
|
|
|
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))
|
2023-01-05 20:51:45 +00:00
|
|
|
}
|
|
|
|
})
|
2023-09-25 02:28:46 +00:00
|
|
|
} 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{
|
2023-09-25 02:28:46 +00:00
|
|
|
"json": field.Name,
|
|
|
|
"url": field.Name + ",omitempty",
|
|
|
|
})
|
|
|
|
}
|
2023-01-05 20:51:45 +00:00
|
|
|
|
2023-09-25 02:28:46 +00:00
|
|
|
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"})
|
2023-01-05 20:51:45 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return f.Render(s.w)
|
|
|
|
}
|
2023-09-25 02:28:46 +00:00
|
|
|
|
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)
|
2023-09-25 02:28:46 +00:00
|
|
|
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:28:46 +00:00
|
|
|
}
|
|
|
|
|
2023-09-25 02:36:37 +00:00
|
|
|
func transformType(name, t string) string {
|
|
|
|
switch t {
|
2023-09-25 02:28:46 +00:00
|
|
|
case "number":
|
2023-09-25 03:16:12 +00:00
|
|
|
return "int64"
|
2023-09-25 02:28:46 +00:00
|
|
|
case "boolean":
|
|
|
|
return "bool"
|
|
|
|
default:
|
2023-09-25 02:36:37 +00:00
|
|
|
return t
|
2023-09-25 02:28:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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",
|
2023-09-25 03:16:12 +00:00
|
|
|
"Totp", "TOTP",
|
|
|
|
"2fa", "2FA",
|
2023-09-25 03:51:23 +00:00
|
|
|
"Png", "PNG",
|
|
|
|
"Uuid", "UUID",
|
|
|
|
"Wav", "WAV",
|
2023-09-25 02:28:46 +00:00
|
|
|
).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()
|
|
|
|
}
|