json tags and separate template file
This commit is contained in:
parent
41ada2851f
commit
478450f474
|
@ -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)
|
||||||
|
|
165
skylab/templates/golang.go.tmpl
Normal file
165
skylab/templates/golang.go.tmpl
Normal 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}}
|
||||||
|
|
Loading…
Reference in a new issue