Convert to templates

Signed-off-by: jolheiser <john.olheiser@gmail.com>
This commit is contained in:
jolheiser
2021-08-06 14:05:10 -05:00
parent ba26dc6adc
commit 782f70ba21
10 changed files with 21461 additions and 4677 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6,24 +6,56 @@ package main
import (
"encoding/json"
"fmt"
"go/ast"
"go/format"
"go/token"
"net/http"
"os"
"reflect"
"strconv"
"text/template"
"github.com/iancoleman/strcase"
)
const (
infoURL = "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc/1.17/entities.json"
//language=gohtml
entityTmpl = `// Code generated by gen_entity.go DO NOT EDIT.
// Package entity stores information about entities in Minecraft.
package entity
// ID describes the numeric ID of an entity.
type ID uint32
// Entity describes information about a type of entity.
type Entity struct {
ID ID
InternalID uint32
DisplayName string
Name string
Width float64
Height float64
Type string
}
var (
{{- range .}}
{{.CamelName}} = Entity{
ID: {{.ID}},
InternalID: {{.InternalID}},
DisplayName: "{{.DisplayName}}",
Name: "{{.Name}}",
Width: {{.Width}},
Height: {{.Height}},
Type: "{{.Type}}",
}{{end}}
)
// ByID is an index of minecraft entities by their ID.
var ByID = map[ID]*Entity{ {{range .}}
{{.ID}}: &{{.CamelName}},{{end}}
}`
)
type Entity struct {
ID uint32 `json:"id"`
InternalID uint32 `json:"internalId"`
CamelName string `json:"-"`
DisplayName string `json:"displayName"`
Name string `json:"name"`
@ -33,121 +65,39 @@ type Entity struct {
Type string `json:"type"`
}
func downloadInfo() ([]Entity, error) {
func downloadInfo() ([]*Entity, error) {
resp, err := http.Get(infoURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var data []Entity
var data []*Entity
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err
}
return data, nil
}
func makeEntityDeclaration(entities []Entity) *ast.DeclStmt {
out := &ast.DeclStmt{Decl: &ast.GenDecl{Tok: token.VAR}}
for _, e := range entities {
t := reflect.TypeOf(e)
fields := make([]ast.Expr, t.NumField())
for i := 0; i < t.NumField(); i++ {
ft := t.Field(i)
var val ast.Expr
switch ft.Type.Kind() {
case reflect.Uint32, reflect.Int:
val = &ast.BasicLit{Kind: token.INT, Value: fmt.Sprint(reflect.ValueOf(e).Field(i))}
case reflect.Float64:
val = &ast.BasicLit{Kind: token.FLOAT, Value: fmt.Sprint(reflect.ValueOf(e).Field(i))}
case reflect.String:
val = &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(reflect.ValueOf(e).Field(i).String())}
case reflect.Bool:
val = &ast.BasicLit{Kind: token.IDENT, Value: fmt.Sprint(reflect.ValueOf(e).Field(i).Bool())}
case reflect.Slice:
val = &ast.CompositeLit{
Type: &ast.ArrayType{
Elt: &ast.BasicLit{Kind: token.IDENT, Value: ft.Type.Elem().Name()},
},
}
v := reflect.ValueOf(e).Field(i)
switch ft.Type.Elem().Kind() {
case reflect.Uint32, reflect.Int:
for x := 0; x < v.Len(); x++ {
val.(*ast.CompositeLit).Elts = append(val.(*ast.CompositeLit).Elts, &ast.BasicLit{
Kind: token.INT,
Value: fmt.Sprint(v.Index(x)),
})
}
}
}
fields[i] = &ast.KeyValueExpr{
Key: &ast.Ident{Name: ft.Name},
Value: val,
}
}
out.Decl.(*ast.GenDecl).Specs = append(out.Decl.(*ast.GenDecl).Specs, &ast.ValueSpec{
Names: []*ast.Ident{{Name: strcase.ToCamel(e.Name)}},
Values: []ast.Expr{
&ast.CompositeLit{
Type: &ast.Ident{Name: reflect.TypeOf(e).Name()},
Elts: fields,
},
},
})
for _, d := range data {
d.CamelName = strcase.ToCamel(d.Name)
}
return out
return data, nil
}
//go:generate go run $GOFILE
//go:generate go fmt entity.go
func main() {
fmt.Println("generating entity.go")
entities, err := downloadInfo()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
panic(err)
}
f, err := os.Create("entity.go")
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
panic(err)
}
defer f.Close()
fmt.Fprintln(f, `// Code generated by gen_entity.go DO NOT EDIT.
// Package entity stores information about entities in Minecraft.
package entity
// ID describes the numeric ID of an entity.
type ID uint32
// Entity describes information about a type of entity.
type Entity struct {
ID ID
InternalID uint32
DisplayName string
Name string
Width float64
Height float64
Type string
}`)
format.Node(f, token.NewFileSet(), makeEntityDeclaration(entities))
fmt.Fprintln(f)
fmt.Fprintln(f)
fmt.Fprintln(f, "// ByID is an index of minecraft entities by their ID.")
fmt.Fprintln(f, "var ByID = map[ID]*Entity{")
for _, e := range entities {
fmt.Fprintf(f, " %d: &%s,\n", e.ID, strcase.ToCamel(e.Name))
if err := template.Must(template.New("").Parse(entityTmpl)).Execute(f, entities); err != nil {
panic(err)
}
fmt.Fprintln(f, "}")
fmt.Fprintln(f)
}