package generate import "fmt" import "maps" import "slices" import "crypto/md5" type Protocol struct { Messages map[uint16] Message Types map[string] Type } type Message struct { Name string Type Type } type Type interface { fmt.Stringer } type TypeInt struct { Bits int Signed bool } func (typ TypeInt) String() string { output := "" if typ.Signed { output += "I" } else { output += "U" } output += fmt.Sprint(typ.Bits) return output } type TypeFloat struct { Bits int } func (typ TypeFloat) String() string { return fmt.Sprintf("F%d", typ.Bits) } type TypeString struct { } func (TypeString) String() string { return "String" } type TypeBuffer struct { } func (TypeBuffer) String() string { return "Buffer" } type TypeArray struct { Element Type } func (typ TypeArray) String() string { return fmt.Sprintf("[]%v", typ.Element) } type TypeTable struct { } func (TypeTable) String() string { return "Table" } type TypeTableDefined struct { Fields map[uint16] Field } func (typ TypeTableDefined) String() string { output := "{" for _, key := range slices.Sorted(maps.Keys(typ.Fields)) { output += fmt.Sprintf("%04X %v", key, typ.Fields[key]) } output += "}" return output } type Field struct { Name string Type Type } func (field Field) String() string { return fmt.Sprintf("%s %v", field.Name, field.Type) } type TypeNamed struct { Name string } func (typ TypeNamed) String() string { return typ.Name } func HashType(typ Type) [16]byte { // TODO: if we ever want to make the compiler more efficient, this would // be a good place to start, complex string concatenation in a hot path // (sorta) return md5.Sum([]byte(typ.String())) }