Rewrite generator and update for Lemmy 0.18.3

This commit is contained in:
2023-09-24 19:28:46 -07:00
parent 9f4bae88f2
commit 44dbe8c934
62 changed files with 3034 additions and 4194 deletions

View File

@@ -5,7 +5,7 @@ import (
"strings"
"github.com/dave/jennifer/jen"
"go.elara.ws/go-lemmy/cmd/gen/parser"
"go.elara.ws/go-lemmy/cmd/gen/extractor"
)
type RoutesGenerator struct {
@@ -17,23 +17,30 @@ func NewRoutes(w io.Writer, pkgName string) *RoutesGenerator {
return &RoutesGenerator{w, pkgName}
}
func (r *RoutesGenerator) Generate(routes []parser.Route, impls map[string]string) error {
func (r *RoutesGenerator) Generate(routes []extractor.Route) error {
f := jen.NewFile(r.PkgName)
f.HeaderComment("Code generated by go.elara.ws/go-lemmy/cmd/gen (routes generator). DO NOT EDIT.")
for _, r := range routes {
resStruct := impls[r.Struct]
f.Comment(r.Summary)
f.Func().Params(
jen.Id("c").Id("*Client"),
).Id(transformName(r.Struct)).Params(
).Id(transformName(r.Name)).Params(
jen.Id("ctx").Qual("context", "Context"),
jen.Id("data").Qual("go.elara.ws/go-lemmy/types", r.Struct),
).Params(
jen.Op("*").Qual("go.elara.ws/go-lemmy/types", resStruct),
jen.Error(),
).BlockFunc(func(g *jen.Group) {
g.Id("resData").Op(":=").Op("&").Qual("go.elara.ws/go-lemmy/types", resStruct).Block()
jen.Id("data").Qual("go.elara.ws/go-lemmy/types", r.ParamsName),
).ParamsFunc(func(g *jen.Group) {
if r.ReturnName != "" {
g.Op("*").Qual("go.elara.ws/go-lemmy/types", r.ReturnName)
}
g.Error()
}).BlockFunc(func(g *jen.Group) {
returnName := r.ReturnName
if returnName == "" {
returnName = "EmptyResponse"
}
g.Id("resData").Op(":=").Op("&").Qual("go.elara.ws/go-lemmy/types", returnName).Block()
var funcName string
switch r.Method {
@@ -46,16 +53,28 @@ func (r *RoutesGenerator) Generate(routes []parser.Route, impls map[string]strin
g.List(jen.Id("res"), jen.Err()).Op(":=").Id("c").Dot(funcName).Params(
jen.Id("ctx"), jen.Lit(r.Method), jen.Lit(r.Path), jen.Id("data"), jen.Op("&").Id("resData"),
)
g.If(jen.Err().Op("!=").Nil()).Block(
jen.Return(jen.Nil(), jen.Err()),
)
g.If(jen.Err().Op("!=").Nil()).BlockFunc(func(g *jen.Group) {
if returnName == "EmptyResponse" {
g.Return(jen.Err())
} else {
g.Return(jen.Nil(), jen.Err())
}
})
g.Err().Op("=").Id("resError").Params(jen.Id("res"), jen.Id("resData").Dot("LemmyResponse"))
g.If(jen.Err().Op("!=").Nil()).Block(
jen.Return(jen.Nil(), jen.Err()),
)
g.If(jen.Err().Op("!=").Nil()).BlockFunc(func(g *jen.Group) {
if returnName == "EmptyResponse" {
g.Return(jen.Err())
} else {
g.Return(jen.Nil(), jen.Err())
}
})
g.Return(jen.Id("resData"), jen.Nil())
if returnName == "EmptyResponse" {
g.Return(jen.Nil())
} else {
g.Return(jen.Id("resData"), jen.Nil())
}
})
}
@@ -63,6 +82,7 @@ func (r *RoutesGenerator) Generate(routes []parser.Route, impls map[string]strin
}
func transformName(s string) string {
s = strings.ToUpper(s[:1]) + s[1:]
s = strings.TrimPrefix(s, "Get")
s = strings.TrimPrefix(s, "List")
return s

View File

@@ -3,9 +3,10 @@ package generator
import (
"io"
"strings"
"unicode"
"github.com/dave/jennifer/jen"
"go.elara.ws/go-lemmy/cmd/gen/parser"
"go.elara.ws/go-lemmy/cmd/gen/extractor"
)
type StructGenerator struct {
@@ -17,36 +18,88 @@ func NewStruct(w io.Writer, pkgName string) *StructGenerator {
return &StructGenerator{w, pkgName}
}
func (s *StructGenerator) Generate(items []parser.Item) error {
func (s *StructGenerator) Generate(items []extractor.Struct) error {
f := jen.NewFile(s.PkgName)
f.HeaderComment("Code generated by go.elara.ws/go-lemmy/cmd/gen (struct generator). DO NOT EDIT.")
for _, item := range items {
if item.Struct != nil {
st := item.Struct
f.Type().Id(st.Name).StructFunc(func(g *jen.Group) {
for _, field := range st.Fields {
g.Id(field.Name).Id(field.Type).Tag(map[string]string{
"json": field.OrigName,
"url": field.OrigName + ",omitempty",
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 {
g.Id(transformFieldName(field.Name)).Id(getType(field)).Tag(map[string]string{
"json": field.Name,
"url": field.Name + ",omitempty",
})
}
if strings.HasSuffix(st.Name, "Response") {
if strings.HasSuffix(item.Name, "Response") {
g.Id("LemmyResponse")
}
})
} else if item.Enum != nil {
e := item.Enum
f.Type().Id(e.Name).String()
f.Const().DefsFunc(func(g *jen.Group) {
for _, member := range e.Members {
g.Id(e.Name + string(member)).Id(e.Name).Op("=").Lit(string(member))
}
})
}
}
return f.Render(s.w)
}
func getType(f extractor.Field) string {
t := transformType(f.Type)
if f.IsArray {
t = "[]" + t
}
if f.IsOptional {
t = "Optional[" + t + "]"
}
return t
}
func transformType(s string) string {
switch s {
case "number":
return "float64"
case "boolean":
return "bool"
default:
return s
}
}
func transformFieldName(s string) string {
s = snakeToCamel(s)
s = strings.NewReplacer(
"Id", "ID",
"Url", "URL",
"Nsfw", "NSFW",
"Jwt", "JWT",
"Crud", "CRUD",
).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()
}