Move enum-generate to goext
This commit is contained in:
parent
e825b4dd85
commit
562bac6987
@ -1,295 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/rext"
|
||||
"io"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/bfcodegen"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type EnumDefVal struct {
|
||||
VarName string
|
||||
Value string
|
||||
Description *string
|
||||
}
|
||||
|
||||
type EnumDef struct {
|
||||
File string
|
||||
EnumTypeName string
|
||||
Type string
|
||||
Values []EnumDefVal
|
||||
}
|
||||
|
||||
var rexPackage = rext.W(regexp.MustCompile("^package\\s+(?P<name>[A-Za-z0-9_]+)\\s*$"))
|
||||
|
||||
var rexEnumDef = rext.W(regexp.MustCompile("^\\s*type\\s+(?P<name>[A-Za-z0-9_]+)\\s+(?P<type>[A-Za-z0-9_]+)\\s*//\\s*(@enum:type).*$"))
|
||||
|
||||
var rexValueDef = rext.W(regexp.MustCompile("^\\s*(?P<name>[A-Za-z0-9_]+)\\s+(?P<type>[A-Za-z0-9_]+)\\s*=\\s*(?P<value>(\"[A-Za-z0-9_]+\"|[0-9]+))\\s*(//(?P<descr>.*))?.*$"))
|
||||
|
||||
func main() {
|
||||
dest := os.Args[2]
|
||||
|
||||
wd, err := os.Getwd()
|
||||
errpanic(err)
|
||||
|
||||
files, err := os.ReadDir(wd)
|
||||
errpanic(err)
|
||||
|
||||
allEnums := make([]EnumDef, 0)
|
||||
|
||||
pkgname := ""
|
||||
|
||||
for _, f := range files {
|
||||
if !strings.HasSuffix(f.Name(), ".go") {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("========= %s =========\n\n", f.Name())
|
||||
fileEnums, pn := processFile(f.Name())
|
||||
fmt.Printf("\n")
|
||||
|
||||
allEnums = append(allEnums, fileEnums...)
|
||||
|
||||
if pn != "" {
|
||||
pkgname = pn
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if pkgname == "" {
|
||||
panic("no package name found in any file")
|
||||
}
|
||||
|
||||
errpanic(os.WriteFile(dest, []byte(fmtOutput(allEnums, pkgname)), 0o755))
|
||||
}
|
||||
|
||||
func errpanic(err error) {
|
||||
err = bfcodegen.GenerateEnumSpecs(wd, dest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func processFile(fn string) ([]EnumDef, string) {
|
||||
file, err := os.Open(fn)
|
||||
errpanic(err)
|
||||
defer func() { errpanic(file.Close()) }()
|
||||
|
||||
bin, err := io.ReadAll(file)
|
||||
errpanic(err)
|
||||
|
||||
lines := strings.Split(string(bin), "\n")
|
||||
|
||||
enums := make([]EnumDef, 0)
|
||||
|
||||
pkgname := ""
|
||||
|
||||
for i, line := range lines {
|
||||
if i == 0 && strings.HasPrefix(line, "// Code generated by") {
|
||||
break
|
||||
}
|
||||
|
||||
if match, ok := rexPackage.MatchFirst(line); i == 0 && ok {
|
||||
pkgname = match.GroupByName("name").Value()
|
||||
continue
|
||||
}
|
||||
|
||||
if match, ok := rexEnumDef.MatchFirst(line); ok {
|
||||
def := EnumDef{
|
||||
File: fn,
|
||||
EnumTypeName: match.GroupByName("name").Value(),
|
||||
Type: match.GroupByName("type").Value(),
|
||||
Values: make([]EnumDefVal, 0),
|
||||
}
|
||||
enums = append(enums, def)
|
||||
fmt.Printf("Found enum definition { '%s' -> '%s' }\n", def.EnumTypeName, def.Type)
|
||||
}
|
||||
|
||||
if match, ok := rexValueDef.MatchFirst(line); ok {
|
||||
typename := match.GroupByName("type").Value()
|
||||
def := EnumDefVal{
|
||||
VarName: match.GroupByName("name").Value(),
|
||||
Value: match.GroupByName("value").Value(),
|
||||
Description: match.GroupByNameOrEmpty("descr").ValueOrNil(),
|
||||
}
|
||||
|
||||
found := false
|
||||
for i, v := range enums {
|
||||
if v.EnumTypeName == typename {
|
||||
enums[i].Values = append(enums[i].Values, def)
|
||||
found = true
|
||||
if def.Description != nil {
|
||||
fmt.Printf("Found enum value [%s] for '%s' ('%s')\n", def.Value, def.VarName, *def.Description)
|
||||
} else {
|
||||
fmt.Printf("Found enum value [%s] for '%s'\n", def.Value, def.VarName)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
fmt.Printf("Found non-enum value [%s] for '%s' ( looks like enum value, but no matching @enum:type )\n", def.Value, def.VarName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return enums, pkgname
|
||||
}
|
||||
|
||||
func fmtOutput(enums []EnumDef, pkgname string) string {
|
||||
str := "// Code generated by permissions_gen.sh DO NOT EDIT.\n"
|
||||
str += "\n"
|
||||
str += "package " + pkgname + "\n"
|
||||
str += "\n"
|
||||
|
||||
str += "import \"gogs.mikescher.com/BlackForestBytes/goext/langext\"" + "\n"
|
||||
str += "\n"
|
||||
|
||||
str += "type Enum interface {" + "\n"
|
||||
str += " Valid() bool" + "\n"
|
||||
str += " ValuesAny() []any" + "\n"
|
||||
str += " ValuesMeta() []EnumMetaValue" + "\n"
|
||||
str += " VarName() string" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "type StringEnum interface {" + "\n"
|
||||
str += " Enum" + "\n"
|
||||
str += " String() string" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "type DescriptionEnum interface {" + "\n"
|
||||
str += " Enum" + "\n"
|
||||
str += " Description() string" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "\n"
|
||||
|
||||
str += "type EnumMetaValue struct {" + "\n"
|
||||
str += " VarName string `json:\"varName\"`" + "\n"
|
||||
str += " Value any `json:\"value\"`" + "\n"
|
||||
str += " Description *string `json:\"description\"`" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "\n"
|
||||
|
||||
for _, enumdef := range enums {
|
||||
|
||||
hasDescr := langext.ArrAll(enumdef.Values, func(val EnumDefVal) bool { return val.Description != nil })
|
||||
hasStr := enumdef.Type == "string"
|
||||
|
||||
str += "// ================================ " + enumdef.EnumTypeName + " ================================" + "\n"
|
||||
str += "//" + "\n"
|
||||
str += "// File: " + enumdef.File + "\n"
|
||||
str += "// StringEnum: " + langext.Conditional(hasStr, "true", "false") + "\n"
|
||||
str += "// DescrEnum: " + langext.Conditional(hasDescr, "true", "false") + "\n"
|
||||
str += "//" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "var __" + enumdef.EnumTypeName + "Values = []" + enumdef.EnumTypeName + "{" + "\n"
|
||||
for _, v := range enumdef.Values {
|
||||
str += " " + v.VarName + "," + "\n"
|
||||
}
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
if hasDescr {
|
||||
str += "var __" + enumdef.EnumTypeName + "Descriptions = map[" + enumdef.EnumTypeName + "]string{" + "\n"
|
||||
for _, v := range enumdef.Values {
|
||||
str += " " + v.VarName + ": \"" + strings.TrimSpace(*v.Description) + "\"," + "\n"
|
||||
}
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
}
|
||||
|
||||
str += "var __" + enumdef.EnumTypeName + "Varnames = map[" + enumdef.EnumTypeName + "]string{" + "\n"
|
||||
for _, v := range enumdef.Values {
|
||||
str += " " + v.VarName + ": \"" + v.VarName + "\"," + "\n"
|
||||
}
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (e " + enumdef.EnumTypeName + ") Valid() bool {" + "\n"
|
||||
str += " return langext.InArray(e, __" + enumdef.EnumTypeName + "Values)" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (e " + enumdef.EnumTypeName + ") Values() []" + enumdef.EnumTypeName + " {" + "\n"
|
||||
str += " return __" + enumdef.EnumTypeName + "Values" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (e " + enumdef.EnumTypeName + ") ValuesAny() []any {" + "\n"
|
||||
str += " return langext.ArrCastToAny(__" + enumdef.EnumTypeName + "Values)" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (e " + enumdef.EnumTypeName + ") ValuesMeta() []EnumMetaValue {" + "\n"
|
||||
str += " return []EnumMetaValue{" + "\n"
|
||||
for _, v := range enumdef.Values {
|
||||
if hasDescr {
|
||||
str += " " + fmt.Sprintf("EnumMetaValue{VarName: \"%s\", Value: %s, Description: langext.Ptr(\"%s\")},", v.VarName, v.VarName, strings.TrimSpace(*v.Description)) + "\n"
|
||||
} else {
|
||||
str += " " + fmt.Sprintf("EnumMetaValue{VarName: \"%s\", Value: %s, Description: nil},", v.VarName, v.VarName) + "\n"
|
||||
}
|
||||
}
|
||||
str += " }" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
if hasStr {
|
||||
str += "func (e " + enumdef.EnumTypeName + ") String() string {" + "\n"
|
||||
str += " return string(e)" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
}
|
||||
|
||||
if hasDescr {
|
||||
str += "func (e " + enumdef.EnumTypeName + ") Description() string {" + "\n"
|
||||
str += " if d, ok := __" + enumdef.EnumTypeName + "Descriptions[e]; ok {" + "\n"
|
||||
str += " return d" + "\n"
|
||||
str += " }" + "\n"
|
||||
str += " return \"\"" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
}
|
||||
|
||||
str += "func (e " + enumdef.EnumTypeName + ") VarName() string {" + "\n"
|
||||
str += " if d, ok := __" + enumdef.EnumTypeName + "Varnames[e]; ok {" + "\n"
|
||||
str += " return d" + "\n"
|
||||
str += " }" + "\n"
|
||||
str += " return \"\"" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func Parse" + enumdef.EnumTypeName + "(vv string) (" + enumdef.EnumTypeName + ", bool) {" + "\n"
|
||||
str += " for _, ev := range __" + enumdef.EnumTypeName + "Values {" + "\n"
|
||||
str += " if string(ev) == vv {" + "\n"
|
||||
str += " return ev, true" + "\n"
|
||||
str += " }" + "\n"
|
||||
str += " }" + "\n"
|
||||
str += " return \"\", false" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func " + enumdef.EnumTypeName + "Values() []" + enumdef.EnumTypeName + " {" + "\n"
|
||||
str += " return __" + enumdef.EnumTypeName + "Values" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func " + enumdef.EnumTypeName + "ValuesMeta() []EnumMetaValue {" + "\n"
|
||||
str += " return []EnumMetaValue{" + "\n"
|
||||
for _, v := range enumdef.Values {
|
||||
if hasDescr {
|
||||
str += " " + fmt.Sprintf("EnumMetaValue{VarName: \"%s\", Value: %s, Description: langext.Ptr(\"%s\")},", v.VarName, v.VarName, strings.TrimSpace(*v.Description)) + "\n"
|
||||
} else {
|
||||
str += " " + fmt.Sprintf("EnumMetaValue{VarName: \"%s\", Value: %s, Description: nil},", v.VarName, v.VarName) + "\n"
|
||||
}
|
||||
}
|
||||
str += " }" + "\n"
|
||||
str += "}" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ require (
|
||||
github.com/jmoiron/sqlx v1.3.5
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/rs/zerolog v1.28.0
|
||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.127
|
||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.130
|
||||
gopkg.in/loremipsum.v1 v1.1.0
|
||||
)
|
||||
|
||||
|
@ -83,6 +83,8 @@ gogs.mikescher.com/BlackForestBytes/goext v0.0.126 h1:o3u0STRaPkmNBenqzvXAOPALSy
|
||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.126/go.mod h1:w8JlyUHpoOJmW5GxsiheZkFh3vn8Mp80ynSVOFLszL0=
|
||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.127 h1:NYrSO1kjFWL1yMh0xqIeMZ4hUJiGjILMQwvZMLy4VEg=
|
||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.127/go.mod h1:w8JlyUHpoOJmW5GxsiheZkFh3vn8Mp80ynSVOFLszL0=
|
||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.130 h1:Gc50AWtjEQK9db7Osz7EFvW/hTwXBVQSAuadsBm6Cj4=
|
||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.130/go.mod h1:w8JlyUHpoOJmW5GxsiheZkFh3vn8Mp80ynSVOFLszL0=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
|
||||
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
||||
|
Loading…
Reference in New Issue
Block a user