Added int attribute type
This commit is contained in:
@ -19,59 +19,67 @@ func identifier(s string) string {
|
||||
return strings.Join(words, "")
|
||||
}
|
||||
|
||||
var attribTypes = map[string]string {
|
||||
"string": `// %[1]s creates a "%[2]s" attribute
|
||||
func %[1]s(value string) hatmill.Attrib {
|
||||
return hatmill.Attrib{
|
||||
Key: "%[2]s",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
`,
|
||||
type AttribTypeInfo struct {
|
||||
Template string
|
||||
Imports []string
|
||||
}
|
||||
|
||||
"bool": `// %[1]s creates a "%[2]s" attribute
|
||||
func %[1]s() hatmill.Attrib {
|
||||
return hatmill.Attrib{
|
||||
Key: "%[2]s",
|
||||
var attribTypes = map[string]AttribTypeInfo{
|
||||
"string": {
|
||||
Template: `// %[1]s creates a "%[2]s" attribute
|
||||
func %[1]s(value string) hatmill.Attrib {
|
||||
return hatmill.Attrib{
|
||||
Key: "%[2]s",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
`,
|
||||
},
|
||||
|
||||
"bool": {
|
||||
Template: `// %[1]s creates a "%[2]s" attribute
|
||||
func %[1]s() hatmill.Attrib {
|
||||
return hatmill.Attrib{
|
||||
Key: "%[2]s",
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
|
||||
"int": {
|
||||
Template: `// %[1]s creates a "%[2]s" attribute
|
||||
func %[1]s(value int) hatmill.Attrib {
|
||||
return hatmill.Attrib{
|
||||
Key: "%[2]s",
|
||||
Value: strconv.FormatInt(int64(value), 10),
|
||||
}
|
||||
}
|
||||
`,
|
||||
Imports: []string{"strconv"},
|
||||
},
|
||||
}
|
||||
|
||||
// Def represents a top-level definition and its required imports.
|
||||
type Def struct {
|
||||
Source string
|
||||
Imports []string
|
||||
}
|
||||
|
||||
type Spec interface {
|
||||
Generate() Def
|
||||
}
|
||||
|
||||
type AttribSpec struct {
|
||||
Name string `json:"name"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type AttribSpecs []AttribSpec
|
||||
|
||||
func (a AttribSpecs) Code() Code {
|
||||
var c Code
|
||||
const hatmillImport = "gitlab.codemonkeysoftware.net/b/hatmill"
|
||||
|
||||
c.Imports = append(c.Imports, hatmillImport)
|
||||
for _, spec := range a {
|
||||
c.Defs = append(c.Defs, spec.Generate())
|
||||
func (spec AttribSpec) Generate() Def {
|
||||
template := attribTypes[spec.Type].Template
|
||||
return Def{
|
||||
Source: fmt.Sprintf(template, identifier(spec.Name), spec.Name),
|
||||
Imports: attribTypes[spec.Type].Imports,
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
type ElemSpecs []ElemSpec
|
||||
|
||||
func (e ElemSpecs) Code() Code {
|
||||
var c Code
|
||||
const hatmillImport = "gitlab.codemonkeysoftware.net/b/hatmill"
|
||||
|
||||
c.Imports = append(c.Imports, hatmillImport)
|
||||
for _, spec := range e {
|
||||
c.Defs = append(c.Defs, spec.Generate())
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (def AttribSpec) Generate() string {
|
||||
template := attribTypes[def.Type]
|
||||
return fmt.Sprintf(template, identifier(def.Name), def.Name)
|
||||
}
|
||||
|
||||
type ElemSpec struct {
|
||||
@ -79,7 +87,7 @@ type ElemSpec struct {
|
||||
Void bool `json:"void"`
|
||||
}
|
||||
|
||||
func (def ElemSpec) Generate() string {
|
||||
func (spec ElemSpec) Generate() Def {
|
||||
const (
|
||||
parentTemplate = `// %[1]s creates a <%[2]s> element.
|
||||
func %[1]s(attribs ...hatmill.Attrib) func(children ...hatmill.Term) hatmill.ParentElement {
|
||||
@ -105,48 +113,52 @@ func (def ElemSpec) Generate() string {
|
||||
)
|
||||
|
||||
template := parentTemplate
|
||||
if def.Void {
|
||||
if spec.Void {
|
||||
template = voidTemplate
|
||||
}
|
||||
return fmt.Sprintf(template, identifier(def.Name), def.Name)
|
||||
return Def{
|
||||
Source: fmt.Sprintf(template, identifier(spec.Name), spec.Name),
|
||||
}
|
||||
}
|
||||
|
||||
type Specs struct {
|
||||
Attributes AttribSpecs `json:"attributes"`
|
||||
Elements ElemSpecs `json:"elements"`
|
||||
}
|
||||
|
||||
// Code is a very slight abstraction of a source code file.
|
||||
type Code struct {
|
||||
Package string
|
||||
Imports []string
|
||||
Defs []string
|
||||
}
|
||||
|
||||
func (c Code) Bytes() ([]byte, error) {
|
||||
func Render(defs []Def, pkgName string) ([]byte, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.WriteString(`// GENERATED BY gitlab.codemonkeysoftware.net/b/hatmill/internal/codegen
|
||||
// DO NOT EDIT!
|
||||
|
||||
`)
|
||||
fmt.Fprintln(buf, "package ", c.Package)
|
||||
for _, imp := range c.Imports {
|
||||
fmt.Fprintln(buf, "package ", pkgName)
|
||||
buf.WriteString(`import "gitlab.codemonkeysoftware.net/b/hatmill"
|
||||
`)
|
||||
|
||||
// Print each import only once.
|
||||
imports := make(map[string]struct{})
|
||||
for _, def := range defs {
|
||||
for _, imp := range def.Imports {
|
||||
imports[imp] = struct{}{}
|
||||
}
|
||||
}
|
||||
for imp := range imports {
|
||||
fmt.Fprintf(buf, "import \"%s\"\n", imp)
|
||||
}
|
||||
for _, def := range c.Defs {
|
||||
buf.WriteString(def)
|
||||
|
||||
for _, def := range defs {
|
||||
buf.WriteString(def.Source)
|
||||
}
|
||||
return format.Source(buf.Bytes())
|
||||
|
||||
formatted, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
err = fmt.Errorf("generated invalid code: %s\nSource code:\n%s", err, buf)
|
||||
}
|
||||
return formatted, err
|
||||
}
|
||||
|
||||
type Coder interface {
|
||||
Code() Code
|
||||
}
|
||||
|
||||
func WriteCodeFile(c Coder, path, pkg string) error {
|
||||
code := c.Code()
|
||||
code.Package = pkg
|
||||
b, err := code.Bytes()
|
||||
func WriteCodeFile(specs []Spec, path, pkgName string) error {
|
||||
var defs []Def
|
||||
for _, spec := range specs {
|
||||
defs = append(defs, spec.Generate())
|
||||
}
|
||||
b, err := Render(defs, pkgName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -166,19 +178,32 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var specs Specs
|
||||
var specs struct {
|
||||
AttribSpecs []AttribSpec `json:"attributes"`
|
||||
ElemSpecs []ElemSpec `json:"elements"`
|
||||
}
|
||||
|
||||
err = json.Unmarshal(input, &specs)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = WriteCodeFile(specs.Attributes, *attribPath, *attribPkg)
|
||||
var attribSpecs []Spec
|
||||
for _, spec := range specs.AttribSpecs {
|
||||
attribSpecs = append(attribSpecs, spec)
|
||||
}
|
||||
err = WriteCodeFile(attribSpecs, *attribPath, *attribPkg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = WriteCodeFile(specs.Elements, *elemPath, *elemPkg)
|
||||
var elemSpecs []Spec
|
||||
for _, spec := range specs.ElemSpecs {
|
||||
elemSpecs = append(elemSpecs, spec)
|
||||
}
|
||||
err = WriteCodeFile(elemSpecs, *elemPath, *elemPkg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user