v0.0.294 migrate bfcodegen to templates
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 58s
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 58s
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package bfcodegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext"
|
||||
@@ -14,6 +16,7 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -30,6 +33,9 @@ var rexCSIDDef = rext.W(regexp.MustCompile(`^\s*type\s+(?P<name>[A-Za-z0-9_]+)\s
|
||||
|
||||
var rexCSIDChecksumConst = rext.W(regexp.MustCompile(`const ChecksumCharsetIDGenerator = "(?P<cs>[A-Za-z0-9_]*)"`))
|
||||
|
||||
//go:embed csid-generate.template
|
||||
var templateCSIDGenerateText string
|
||||
|
||||
func GenerateCharsetIDSpecs(sourceDir string, destFile string) error {
|
||||
|
||||
files, err := os.ReadDir(sourceDir)
|
||||
@@ -168,198 +174,19 @@ func processCSIDFile(basedir string, fn string) ([]CSIDDef, string, error) {
|
||||
}
|
||||
|
||||
func fmtCSIDOutput(cs string, ids []CSIDDef, pkgname string) string {
|
||||
str := "// Code generated by id-generate.go DO NOT EDIT.\n"
|
||||
str += "\n"
|
||||
str += "package " + pkgname + "\n"
|
||||
str += "\n"
|
||||
templ := template.Must(template.New("csid-generate").Parse(templateCSIDGenerateText))
|
||||
|
||||
str += `import "crypto/rand"` + "\n"
|
||||
str += `import "fmt"` + "\n"
|
||||
str += `import "github.com/go-playground/validator/v10"` + "\n"
|
||||
str += `import "github.com/rs/zerolog/log"` + "\n"
|
||||
str += `import "gogs.mikescher.com/BlackForestBytes/goext/exerr"` + "\n"
|
||||
str += `import "gogs.mikescher.com/BlackForestBytes/goext/langext"` + "\n"
|
||||
str += `import "gogs.mikescher.com/BlackForestBytes/goext/rext"` + "\n"
|
||||
str += `import "math/big"` + "\n"
|
||||
str += `import "reflect"` + "\n"
|
||||
str += `import "regexp"` + "\n"
|
||||
str += `import "strings"` + "\n"
|
||||
str += "\n"
|
||||
|
||||
str += "const ChecksumCharsetIDGenerator = \"" + cs + "\" // GoExtVersion: " + goext.GoextVersion + "\n"
|
||||
str += "\n"
|
||||
|
||||
str += "const idlen = 24\n"
|
||||
str += "\n"
|
||||
str += "const checklen = 1\n"
|
||||
str += "\n"
|
||||
str += `const idCharset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"` + "\n"
|
||||
str += "const idCharsetLen = len(idCharset)\n"
|
||||
str += "\n"
|
||||
str += "var charSetReverseMap = generateCharsetMap()\n"
|
||||
str += "\n"
|
||||
str += "const (\n"
|
||||
for _, iddef := range ids {
|
||||
str += " prefix" + iddef.Name + " = \"" + iddef.Prefix + "\"" + "\n"
|
||||
}
|
||||
str += ")\n"
|
||||
str += "\n"
|
||||
str += "var (\n"
|
||||
for _, iddef := range ids {
|
||||
str += " regex" + iddef.Name + " = generateRegex(prefix" + iddef.Name + ")" + "\n"
|
||||
}
|
||||
str += ")\n"
|
||||
str += "\n"
|
||||
str += "func generateRegex(prefix string) rext.Regex {\n"
|
||||
str += " return rext.W(regexp.MustCompile(fmt.Sprintf(\"^%s[%s]{%d}[%s]{%d}$\", prefix, idCharset, idlen-len(prefix)-checklen, idCharset, checklen)))\n"
|
||||
str += "}\n"
|
||||
str += "\n"
|
||||
|
||||
str += `func generateCharsetMap() []int {` + "\n"
|
||||
str += ` result := make([]int, 128)` + "\n"
|
||||
str += ` for i := 0; i < len(result); i++ {` + "\n"
|
||||
str += ` result[i] = -1` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += ` for idx, chr := range idCharset {` + "\n"
|
||||
str += ` result[int(chr)] = idx` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += ` return result` + "\n"
|
||||
str += `}` + "\n"
|
||||
str += "\n"
|
||||
str += `func generateID(prefix string) string {` + "\n"
|
||||
str += ` k := ""` + "\n"
|
||||
str += ` max := big.NewInt(int64(idCharsetLen))` + "\n"
|
||||
str += ` checksum := 0` + "\n"
|
||||
str += ` for i := 0; i < idlen-len(prefix)-checklen; i++ {` + "\n"
|
||||
str += ` v, err := rand.Int(rand.Reader, max)` + "\n"
|
||||
str += ` if err != nil {` + "\n"
|
||||
str += ` panic(err)` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += ` v64 := v.Int64()` + "\n"
|
||||
str += ` k += string(idCharset[v64])` + "\n"
|
||||
str += ` checksum = (checksum + int(v64)) % (idCharsetLen)` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += ` checkstr := string(idCharset[checksum%idCharsetLen])` + "\n"
|
||||
str += ` return prefix + k + checkstr` + "\n"
|
||||
str += `}` + "\n"
|
||||
str += "\n"
|
||||
str += `func validateID(prefix string, value string) error {` + "\n"
|
||||
str += ` if len(value) != idlen {` + "\n"
|
||||
str += ` return exerr.New(exerr.TypeInvalidCSID, "id has the wrong length").Str("value", value).Build()` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += "\n"
|
||||
str += ` if !strings.HasPrefix(value, prefix) {` + "\n"
|
||||
str += ` return exerr.New(exerr.TypeInvalidCSID, "id is missing the correct prefix").Str("value", value).Str("prefix", prefix).Build()` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += "\n"
|
||||
str += ` checksum := 0` + "\n"
|
||||
str += ` for i := len(prefix); i < len(value)-checklen; i++ {` + "\n"
|
||||
str += ` ichr := int(value[i])` + "\n"
|
||||
str += ` if ichr < 0 || ichr >= len(charSetReverseMap) || charSetReverseMap[ichr] == -1 {` + "\n"
|
||||
str += ` return exerr.New(exerr.TypeInvalidCSID, "id contains invalid characters").Str("value", value).Build()` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += ` checksum = (checksum + charSetReverseMap[ichr]) % (idCharsetLen)` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += "\n"
|
||||
str += ` checkstr := string(idCharset[checksum%idCharsetLen])` + "\n"
|
||||
str += "\n"
|
||||
str += ` if !strings.HasSuffix(value, checkstr) {` + "\n"
|
||||
str += ` return exerr.New(exerr.TypeInvalidCSID, "id checkstring is invalid").Str("value", value).Str("checkstr", checkstr).Build()` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += "\n"
|
||||
str += ` return nil` + "\n"
|
||||
str += `}` + "\n"
|
||||
str += "\n"
|
||||
str += `func getRawData(prefix string, value string) string {` + "\n"
|
||||
str += ` if len(value) != idlen {` + "\n"
|
||||
str += ` return ""` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += ` return value[len(prefix) : idlen-checklen]` + "\n"
|
||||
str += `}` + "\n"
|
||||
str += "\n"
|
||||
str += `func getCheckString(prefix string, value string) string {` + "\n"
|
||||
str += ` if len(value) != idlen {` + "\n"
|
||||
str += ` return ""` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += ` return value[idlen-checklen:]` + "\n"
|
||||
str += `}` + "\n"
|
||||
str += "\n"
|
||||
str += `func ValidateEntityID(vfl validator.FieldLevel) bool {` + "\n"
|
||||
str += ` if !vfl.Field().CanInterface() {` + "\n"
|
||||
str += ` log.Error().Msgf("Failed to validate EntityID (cannot interface ?!?)")` + "\n"
|
||||
str += ` return false` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += "\n"
|
||||
str += ` ifvalue := vfl.Field().Interface()` + "\n"
|
||||
str += "\n"
|
||||
str += ` if value1, ok := ifvalue.(EntityID); ok {` + "\n"
|
||||
str += "\n"
|
||||
str += ` if vfl.Field().Type().Kind() == reflect.Pointer && langext.IsNil(value1) {` + "\n"
|
||||
str += ` return true` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += "\n"
|
||||
str += ` if err := value1.Valid(); err != nil {` + "\n"
|
||||
str += ` log.Debug().Msgf("Failed to validate EntityID '%s' (%s)", value1.String(), err.Error())` + "\n"
|
||||
str += ` return false` + "\n"
|
||||
str += ` } else {` + "\n"
|
||||
str += ` return true` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += "\n"
|
||||
str += ` } else {` + "\n"
|
||||
str += ` log.Error().Msgf("Failed to validate EntityID (wrong type: %T)", ifvalue)` + "\n"
|
||||
str += ` return false` + "\n"
|
||||
str += ` }` + "\n"
|
||||
str += `}` + "\n"
|
||||
str += "\n"
|
||||
|
||||
for _, iddef := range ids {
|
||||
|
||||
str += "// ================================ " + iddef.Name + " (" + iddef.FileRelative + ") ================================" + "\n"
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func New" + iddef.Name + "() " + iddef.Name + " {" + "\n"
|
||||
str += " return " + iddef.Name + "(generateID(prefix" + iddef.Name + "))" + "\n"
|
||||
str += "}" + "\n"
|
||||
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (id " + iddef.Name + ") Valid() error {" + "\n"
|
||||
str += " return validateID(prefix" + iddef.Name + ", string(id))" + "\n"
|
||||
str += "}" + "\n"
|
||||
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (i " + iddef.Name + ") String() string {" + "\n"
|
||||
str += " return string(i)" + "\n"
|
||||
str += "}" + "\n"
|
||||
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (i " + iddef.Name + ") Prefix() string {" + "\n"
|
||||
str += " return prefix" + iddef.Name + "" + "\n"
|
||||
str += "}" + "\n"
|
||||
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (id " + iddef.Name + ") Raw() string {" + "\n"
|
||||
str += " return getRawData(prefix" + iddef.Name + ", string(id))" + "\n"
|
||||
str += "}" + "\n"
|
||||
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (id " + iddef.Name + ") CheckString() string {" + "\n"
|
||||
str += " return getCheckString(prefix" + iddef.Name + ", string(id))" + "\n"
|
||||
str += "}" + "\n"
|
||||
|
||||
str += "" + "\n"
|
||||
|
||||
str += "func (id " + iddef.Name + ") Regex() rext.Regex {" + "\n"
|
||||
str += " return regex" + iddef.Name + "" + "\n"
|
||||
str += "}" + "\n"
|
||||
|
||||
str += "" + "\n"
|
||||
buffer := bytes.Buffer{}
|
||||
|
||||
err := templ.Execute(&buffer, langext.H{
|
||||
"PkgName": pkgname,
|
||||
"Checksum": cs,
|
||||
"GoextVersion": goext.GoextVersion,
|
||||
"IDs": ids,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return str
|
||||
return buffer.String()
|
||||
}
|
||||
|
Reference in New Issue
Block a user