json tags and separate template file

This commit is contained in:
saji 2023-05-17 00:01:40 -05:00
parent 41ada2851f
commit 478450f474
2 changed files with 166 additions and 169 deletions

View file

@ -226,173 +226,6 @@ func (p PacketDef) MakeUnmarshal() string {
return buf.String() return buf.String()
} }
var templ = `
{{ define "packet" }}
{{- $structName := camelCase .Name true}}
{{- /* generate any bitfield structs */ -}}
{{range .Data -}}
{{ if .Bits -}}
{{- $bfname := (printf "%s%s" $structName (camelCase .Name true)) }}
type {{$bfname}} struct {
{{- range $el := .Bits}}
{{camelCase $el.Name true}} bool
{{- end}}
}
func (p *{{$bfname}}) Marshal() byte {
var b byte
{{- range $idx, $el := .Bits}}
{{- $bitName := camelCase $el.Name true}}
if p.{{$bitName}} {
b |= 1 << {{$idx}}
}
{{- end}}
return b
}
func (p *{{$bfname}}) Unmarshal(b byte) {
{{- range $idx, $el := .Bits}}
{{- $bitName := camelCase $el.Name true }}
p.{{$bitName}} = (b & (1 << {{ $idx }})) != 0
{{- end}}
}
{{end}}
{{- end}}
// {{$structName}} is {{.Description}}
type {{$structName}} struct {
{{- range .Data}}
{{ if .Units -}} // {{.Conversion}} {{.Units}} {{- end }}
{{.ToStructMember $structName }}
{{- end}}
{{- if .Repeat }}
// Idx is the packet index. The accepted range is 0-{{.Repeat}}
Idx uint32
{{- end }}
}
func (p *{{$structName}}) Id() (uint32, error) {
{{- if .Repeat }}
if p.Idx >= {{.Repeat}} {
return 0, errors.New("invalid packet index")
}
return {{ printf "0x%X" .Id }} + p.Idx, nil
{{- else }}
return {{ printf "0x%X" .Id }}, nil
{{- end }}
}
func (p *{{$structName}}) Size() uint {
return {{.CalcSize}}
}
func (p *{{$structName}}) MarshalPacket() ([]byte, error) {
b := make([]byte, {{ .CalcSize }})
{{.MakeMarshal}}
return b, nil
}
func (p *{{$structName}}) UnmarshalPacket(b []byte) error {
{{.MakeUnmarshal}}
return nil
}
func (p *{{$structName}}) String() string {
return ""
}
{{ end }}
{{- /* begin actual file template */ -}}
// generated by gen_skylab.go at {{ Time }} DO NOT EDIT!
package skylab
import (
"errors"
"encoding/binary"
"encoding/json"
)
type SkylabId uint32
const (
{{- range .Packets }}
{{camelCase .Name true}}Id SkylabId = {{.Id | printf "0x%X"}}
{{- end}}
)
// list of every packet ID. can be used for O(1) checks.
var idMap = map[uint32]bool{
{{ range $p := .Packets -}}
{{ if $p.Repeat }}
{{ range $idx := Nx (int $p.Id) $p.Repeat $p.Offset -}}
{{ $idx | printf "0x%X"}}: true,
{{ end }}
{{- else }}
{{ $p.Id | printf "0x%X" }}: true,
{{- end}}
{{- end}}
}
func FromCanFrame(id uint32, data []byte) (Packet, error) {
if !idMap[id] {
return nil, errors.New("Unknown Id")
}
switch id {
{{- range $p := .Packets }}
{{- if $p.Repeat }}
case {{ Nx (int $p.Id) $p.Repeat $p.Offset | mapf "0x%X" | strJoin ", " -}}:
var res *{{camelCase $p.Name true}}
res.UnmarshalPacket(data)
res.Idx = id - {{$p.Id | printf "0x%X" }}
return res, nil
{{- else }}
case {{ $p.Id | printf "0x%X" }}:
var res *{{camelCase $p.Name true}}
res.UnmarshalPacket(data)
return res, nil
{{- end}}
{{- end}}
}
return nil, errors.New("failed to match Id, something is really wrong!")
}
func FromJson (raw []byte) (Packet, error) {
// attempt to parse the JSON to a JSONPacket
jp := &JSONPacket{}
err := json.Unmarshal(raw, jp)
if err != nil {
return nil, err
}
switch jp.Id {
{{- range $p := .Packets }}
{{- if $p.Repeat }}
case {{ Nx (int $p.Id) $p.Repeat $p.Offset | mapf "0x%X" | strJoin ", " -}}:
var res *{{camelCase $p.Name true}}
err := json.Unmarshal(jp.Data, res)
res.Idx = jp.Id - {{ $p.Id | printf "0x%X" }}
return res, err
{{- else }}
case {{ $p.Id | printf "0x%X" }}:
var res *{{camelCase $p.Name true}}
err := json.Unmarshal(jp.Data, res)
return res, err
{{- end }}
{{- end }}
}
return nil, errors.New("aaa")
}
{{range .Packets -}}
{{template "packet" .}}
{{- end}}
`
// stolen camelCaser code. initCase = true means CamelCase, false means camelCase // stolen camelCaser code. initCase = true means CamelCase, false means camelCase
func toCamelInitCase(s string, initCase bool) string { func toCamelInitCase(s string, initCase bool) string {
@ -502,13 +335,12 @@ func main() {
"strJoin": strJoin, "strJoin": strJoin,
"mapf": mapf, "mapf": mapf,
} }
tmpl, err := template.New("skylab").Funcs(fnMap).Parse(templ) tmpl, err := template.New("golang.go.tmpl").Funcs(fnMap).ParseFiles("templates/golang.go.tmpl")
if err != nil { if err != nil {
panic(err) panic(err)
} }
f, err := os.Create("skylab_gen.go") f, err := os.Create("skylab_gen.go")
if err != nil { if err != nil {
panic(err) panic(err)

View file

@ -0,0 +1,165 @@
{{ define "packet" }}
{{- $structName := camelCase .Name true}}
{{- /* generate any bitfield structs */ -}}
{{range .Data -}}
{{ if .Bits -}}
{{- $bfname := (printf "%s%s" $structName (camelCase .Name true)) }}
type {{$bfname}} struct {
{{- range $el := .Bits}}
{{camelCase $el.Name true}} bool `json:"{{$el.Name}}"`
{{- end}}
}
func (p *{{$bfname}}) Marshal() byte {
var b byte
{{- range $idx, $el := .Bits}}
{{- $bitName := camelCase $el.Name true}}
if p.{{$bitName}} {
b |= 1 << {{$idx}}
}
{{- end}}
return b
}
func (p *{{$bfname}}) Unmarshal(b byte) {
{{- range $idx, $el := .Bits}}
{{- $bitName := camelCase $el.Name true }}
p.{{$bitName}} = (b & (1 << {{ $idx }})) != 0
{{- end}}
}
{{end}}
{{- end}}
// {{$structName}} is {{.Description}}
type {{$structName}} struct {
{{- range .Data}}
{{- if .Units -}} // {{.Conversion}} {{.Units}} {{- end }}
{{ .ToStructMember $structName }} `json:"{{.Name}}"`
{{- end}}
{{- if .Repeat }}
// Idx is the packet index. The accepted range is 0-{{.Repeat}}
Idx uint32
{{- end }}
}
func (p *{{$structName}}) Id() (uint32, error) {
{{- if .Repeat }}
if p.Idx >= {{.Repeat}} {
return 0, errors.New("invalid packet index")
}
return {{ printf "0x%X" .Id }} + p.Idx, nil
{{- else }}
return {{ printf "0x%X" .Id }}, nil
{{- end }}
}
func (p *{{$structName}}) Size() uint {
return {{.CalcSize}}
}
func (p *{{$structName}}) MarshalPacket() ([]byte, error) {
b := make([]byte, {{ .CalcSize }})
{{.MakeMarshal}}
return b, nil
}
func (p *{{$structName}}) UnmarshalPacket(b []byte) error {
{{.MakeUnmarshal}}
return nil
}
func (p *{{$structName}}) String() string {
return ""
}
{{ end }}
{{- /* begin actual file template */ -}}
// generated by gen_skylab.go at {{ Time }} DO NOT EDIT!
package skylab
import (
"errors"
"encoding/binary"
"encoding/json"
)
type SkylabId uint32
const (
{{- range .Packets }}
{{camelCase .Name true}}Id SkylabId = {{.Id | printf "0x%X"}}
{{- end}}
)
// list of every packet ID. can be used for O(1) checks.
var idMap = map[uint32]bool{
{{ range $p := .Packets -}}
{{ if $p.Repeat }}
{{ range $idx := Nx (int $p.Id) $p.Repeat $p.Offset -}}
{{ $idx | printf "0x%X"}}: true,
{{ end }}
{{- else }}
{{ $p.Id | printf "0x%X" }}: true,
{{- end}}
{{- end}}
}
func FromCanFrame(id uint32, data []byte) (Packet, error) {
if !idMap[id] {
return nil, errors.New("Unknown Id")
}
switch id {
{{- range $p := .Packets }}
{{- if $p.Repeat }}
case {{ Nx (int $p.Id) $p.Repeat $p.Offset | mapf "0x%X" | strJoin ", " -}}:
var res *{{camelCase $p.Name true}}
res.UnmarshalPacket(data)
res.Idx = id - {{$p.Id | printf "0x%X" }}
return res, nil
{{- else }}
case {{ $p.Id | printf "0x%X" }}:
var res *{{camelCase $p.Name true}}
res.UnmarshalPacket(data)
return res, nil
{{- end}}
{{- end}}
}
return nil, errors.New("failed to match Id, something is really wrong!")
}
func FromJson (raw []byte) (Packet, error) {
// attempt to parse the JSON to a JSONPacket
jp := &JSONPacket{}
err := json.Unmarshal(raw, jp)
if err != nil {
return nil, err
}
switch jp.Id {
{{- range $p := .Packets }}
{{- if $p.Repeat }}
case {{ Nx (int $p.Id) $p.Repeat $p.Offset | mapf "0x%X" | strJoin ", " -}}:
var res *{{camelCase $p.Name true}}
err := json.Unmarshal(jp.Data, res)
res.Idx = jp.Id - {{ $p.Id | printf "0x%X" }}
return res, err
{{- else }}
case {{ $p.Id | printf "0x%X" }}:
var res *{{camelCase $p.Name true}}
err := json.Unmarshal(jp.Data, res)
return res, err
{{- end }}
{{- end }}
}
return nil, errors.New("aaa")
}
{{range .Packets -}}
{{template "packet" .}}
{{- end}}