Files
arpack/cmd/arpack/main.go
T
2026-03-25 13:02:08 +03:00

153 lines
3.9 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/edmand46/arpack/generator"
"github.com/edmand46/arpack/parser"
)
func main() {
in := flag.String("in", "", "input Go file with struct definitions")
outGo := flag.String("out-go", "", "output directory for generated Go code")
outCS := flag.String("out-cs", "", "output directory for generated C# code")
outTS := flag.String("out-ts", "", "output directory for generated TypeScript code")
outLua := flag.String("out-lua", "", "output directory for generated Lua code")
namespace := flag.String("cs-namespace", "Arpack.Messages", "C# namespace")
flag.Parse()
if *in == "" {
log.Fatal("arpack: -in is required")
}
if *outGo == "" && *outCS == "" && *outTS == "" && *outLua == "" {
log.Fatal("arpack: at least one of -out-go, -out-cs, -out-ts, or -out-lua is required")
}
schema, err := parser.ParseSchemaFile(*in)
if err != nil {
log.Fatalf("arpack: parse error: %v", err)
}
msgs := schema.Messages
if len(msgs) == 0 {
log.Fatalf("arpack: no structs found in %s", *in)
}
baseName := strings.TrimSuffix(filepath.Base(*in), ".go")
if *outGo != "" {
pkgName := filepath.Base(*outGo)
if pkgName == "." || pkgName == "" {
pkgName = msgs[0].PackageName
}
// Replace hyphens with underscores for valid Go package names
pkgName = strings.ReplaceAll(pkgName, "-", "_")
src, err := generator.GenerateGoSchema(schema, pkgName)
if err != nil {
log.Fatalf("arpack: Go generation error: %v", err)
}
outPath := filepath.Join(*outGo, baseName+"_gen.go")
if err := os.MkdirAll(*outGo, 0755); err != nil {
log.Fatalf("arpack: mkdir %s: %v", *outGo, err)
}
if err := os.WriteFile(outPath, src, 0644); err != nil {
log.Fatalf("arpack: write %s: %v", outPath, err)
}
fmt.Printf("arpack: wrote %s\n", outPath)
}
if *outCS != "" {
src, err := generator.GenerateCSharpSchema(schema, *namespace)
if err != nil {
log.Fatalf("arpack: C# generation error: %v", err)
}
outPath := filepath.Join(*outCS, toTitle(baseName)+".gen.cs")
if err := os.MkdirAll(*outCS, 0755); err != nil {
log.Fatalf("arpack: mkdir %s: %v", *outCS, err)
}
if err := os.WriteFile(outPath, src, 0644); err != nil {
log.Fatalf("arpack: write %s: %v", outPath, err)
}
fmt.Printf("arpack: wrote %s\n", outPath)
}
if *outTS != "" {
src, err := generator.GenerateTypeScriptSchema(schema, "Arpack.Messages")
if err != nil {
log.Fatalf("arpack: TypeScript generation error: %v", err)
}
outPath := filepath.Join(*outTS, toTitle(baseName)+".gen.ts")
if err := os.MkdirAll(*outTS, 0755); err != nil {
log.Fatalf("arpack: mkdir %s: %v", *outTS, err)
}
if err := os.WriteFile(outPath, src, 0644); err != nil {
log.Fatalf("arpack: write %s: %v", outPath, err)
}
fmt.Printf("arpack: wrote %s\n", outPath)
}
if *outLua != "" {
src, err := generator.GenerateLuaSchema(schema, baseName)
if err != nil {
log.Fatalf("arpack: Lua generation error: %v", err)
}
// Use snake_case filename for Lua require() compatibility
outPath := filepath.Join(*outLua, toSnakeCase(baseName)+"_gen.lua")
if err := os.MkdirAll(*outLua, 0755); err != nil {
log.Fatalf("arpack: mkdir %s: %v", *outLua, err)
}
if err := os.WriteFile(outPath, src, 0644); err != nil {
log.Fatalf("arpack: write %s: %v", outPath, err)
}
fmt.Printf("arpack: wrote %s\n", outPath)
}
}
func toTitle(s string) string {
return strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
}
func toSnakeCase(s string) string {
if s == "" {
return ""
}
var b strings.Builder
var prevUpper bool
for i, c := range s {
isUpper := c >= 'A' && c <= 'Z'
if i > 0 && isUpper {
nextLower := false
if i+1 < len(s) {
nextChar := rune(s[i+1])
nextLower = nextChar >= 'a' && nextChar <= 'z'
}
if !prevUpper || nextLower {
b.WriteByte('_')
}
}
b.WriteRune(c)
prevUpper = isUpper
}
return strings.ToLower(b.String())
}