Added a new flag/feature to generate json marshaling methods

This commit is contained in:
Álvaro 2016-01-19 19:39:33 +00:00
parent a8751cee5a
commit 06fa207af0
2 changed files with 37 additions and 5 deletions

View File

@ -1,4 +1,5 @@
package main package main
import "fmt" import "fmt"
// Arguments to format are: // Arguments to format are:
@ -33,3 +34,26 @@ func (g *Generator) buildValueToNameMap(runs [][]Value, typeName string, runsThr
g.Printf("}\n\n") g.Printf("}\n\n")
g.Printf(stringValueToNameMap, typeName) g.Printf(stringValueToNameMap, typeName)
} }
// Arguments to format are:
// [1]: type name
const jsonMethods = `
func (i %[1]s) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
func (i *%[1]s) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return fmt.Errorf("%[1]s should be a string, got %%s", data)
}
var err error
*i, err = %[1]sString(s)
return err
}
`
func (g *Generator) buildJSONMethods(runs [][]Value, typeName string, runsThreshold int) {
g.Printf(jsonMethods, typeName)
}

View File

@ -82,6 +82,7 @@ import (
var ( var (
typeNames = flag.String("type", "", "comma-separated list of type names; must be set") typeNames = flag.String("type", "", "comma-separated list of type names; must be set")
noJSON = flag.Bool("noJSON", false, "if true, json marshaling methods will NOT be included. Default: false")
output = flag.String("output", "", "output file name; default srcdir/<type>_string.go") output = flag.String("output", "", "output file name; default srcdir/<type>_string.go")
) )
@ -98,7 +99,7 @@ func Usage() {
func main() { func main() {
log.SetFlags(0) log.SetFlags(0)
log.SetPrefix("stringer: ") log.SetPrefix("enumer: ")
flag.Usage = Usage flag.Usage = Usage
flag.Parse() flag.Parse()
if len(*typeNames) == 0 { if len(*typeNames) == 0 {
@ -133,6 +134,9 @@ func main() {
g.Printf("package %s", g.pkg.name) g.Printf("package %s", g.pkg.name)
g.Printf("\n") g.Printf("\n")
g.Printf("import \"fmt\"\n") // Used by all methods. g.Printf("import \"fmt\"\n") // Used by all methods.
if !*noJSON {
g.Printf("import \"encoding/json\"\n")
}
// Run generate for each type. // Run generate for each type.
for _, typeName := range types { for _, typeName := range types {
@ -300,16 +304,20 @@ func (g *Generator) generate(typeName string) {
// being necessary for any realistic example other than bitmasks // being necessary for any realistic example other than bitmasks
// is very low. And bitmasks probably deserve their own analysis, // is very low. And bitmasks probably deserve their own analysis,
// to be done some other day. // to be done some other day.
const runsThreshold = 10
switch { switch {
case len(runs) == 1: case len(runs) == 1:
g.buildOneRun(runs, typeName) g.buildOneRun(runs, typeName)
case len(runs) <= 10: case len(runs) <= runsThreshold:
g.buildMultipleRuns(runs, typeName) g.buildMultipleRuns(runs, typeName)
default: default:
g.buildMap(runs, typeName) g.buildMap(runs, typeName)
} }
// ENUMER: This is the only addition over the original stringer code. Everything else is in enumer.go // ENUMER part
g.buildValueToNameMap(runs, typeName, 10) g.buildValueToNameMap(runs, typeName, runsThreshold)
if !*noJSON {
g.buildJSONMethods(runs, typeName, runsThreshold)
}
} }
// splitIntoRuns breaks the values into runs of contiguous sequences. // splitIntoRuns breaks the values into runs of contiguous sequences.