package golang import ( "bytes" "fmt" "go/format" "strings" "text/template" _ "embed" "efprojects.com/kitten-ipc/kitcom/internal/api" "efprojects.com/kitten-ipc/kitcom/internal/common" ) //go:embed gogen.tmpl var templateString string type goGenData struct { PkgName string Api *api.Api } type GoApiGenerator struct { PkgName string } func (g *GoApiGenerator) Generate(apis *api.Api, destFile string) error { tplCtx := goGenData{ PkgName: g.PkgName, Api: apis, } tpl := template.New("gogen") tpl = tpl.Funcs(map[string]any{ "receiver": func(name string) string { return strings.ToLower(name[:1]) }, "typedef": func(t api.ValType) (string, error) { td, ok := map[api.ValType]string{ api.TInt: "int", api.TString: "string", api.TBool: "bool", api.TBlob: "[]byte", }[t] if !ok { return "", fmt.Errorf("cannot generate type %v", t) } return td, nil }, "convtype": func(valDef string, t api.ValType) (string, error) { td, ok := map[api.ValType]string{ api.TInt: fmt.Sprintf("int(%s.(float64))", valDef), api.TString: fmt.Sprintf("%s.(string)", valDef), api.TBool: fmt.Sprintf("%s.(bool)", valDef), api.TBlob: fmt.Sprintf("%s.([]byte)", valDef), }[t] if !ok { return "", fmt.Errorf("cannot convert type %v for val %s", t, valDef) } return td, nil }, "zerovalue": func(t api.ValType) (string, error) { v, ok := map[api.ValType]string{ api.TInt: "0", api.TString: `""`, api.TBool: "false", api.TBlob: "[]byte{}", }[t] if !ok { return "", fmt.Errorf("cannot generate zero value for type %v", t) } return v, nil }, }) tpl = template.Must(tpl.Parse(templateString)) var buf bytes.Buffer if err := tpl.ExecuteTemplate(&buf, "gogen", tplCtx); err != nil { return fmt.Errorf("execute template: %w", err) } formatted, err := format.Source(buf.Bytes()) if err != nil { return fmt.Errorf("format source: %w", err) } if err := common.WriteFile(destFile, formatted); err != nil { return fmt.Errorf("write file: %w", err) } return nil }