Skip to content

Commit

Permalink
Merge pull request #42 from ChimeraCoder/add-float-option
Browse files Browse the repository at this point in the history
Add -forcefloats flag (experimental)
  • Loading branch information
ChimeraCoder authored Nov 7, 2016
2 parents f36cdd4 + 08ce479 commit 6039f74
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 25 deletions.
10 changes: 5 additions & 5 deletions examples/example_array.go.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ type Users []struct {
CreatedAt string `json:"created_at"`
Email interface{} `json:"email"`
EventsURL string `json:"events_url"`
Followers int `json:"followers"`
Followers int64 `json:"followers"`
FollowersURL string `json:"followers_url"`
Following int `json:"following"`
Following int64 `json:"following"`
FollowingURL string `json:"following_url"`
GistsURL string `json:"gists_url"`
GravatarID string `json:"gravatar_id"`
Hireable bool `json:"hireable"`
HTMLURL string `json:"html_url"`
ID int `json:"id"`
ID int64 `json:"id"`
Location string `json:"location"`
Login string `json:"login"`
Name string `json:"name"`
OrganizationsURL string `json:"organizations_url"`
PublicGists int `json:"public_gists"`
PublicRepos int `json:"public_repos"`
PublicGists int64 `json:"public_gists"`
PublicRepos int64 `json:"public_repos"`
ReceivedEventsURL string `json:"received_events_url"`
ReposURL string `json:"repos_url"`
SiteAdmin bool `json:"site_admin"`
Expand Down
6 changes: 6 additions & 0 deletions examples/expected_floats.go.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package gojson

type Stats struct {
Count int64 `json:"count"`
Mean float64 `json:"mean"`
}
10 changes: 5 additions & 5 deletions examples/expected_output_array_test.go.out
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ type Users []struct {
CreatedAt string `json:"created_at"`
Email string `json:"email"`
EventsURL string `json:"events_url"`
Followers int `json:"followers"`
Followers int64 `json:"followers"`
FollowersURL string `json:"followers_url"`
Following int `json:"following"`
Following int64 `json:"following"`
FollowingURL string `json:"following_url"`
GistsURL string `json:"gists_url"`
GravatarID string `json:"gravatar_id"`
Hireable bool `json:"hireable"`
HTMLURL string `json:"html_url"`
ID int `json:"id"`
ID int64 `json:"id"`
Location string `json:"location"`
Login string `json:"login"`
Name string `json:"name"`
OrganizationsURL string `json:"organizations_url"`
PublicGists int `json:"public_gists"`
PublicRepos int `json:"public_repos"`
PublicGists int64 `json:"public_gists"`
PublicRepos int64 `json:"public_repos"`
ReceivedEventsURL string `json:"received_events_url"`
ReposURL string `json:"repos_url"`
StarredURL string `json:"starred_url"`
Expand Down
12 changes: 6 additions & 6 deletions examples/expected_output_test.go.out
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
package gojson

type User struct {
OneNumberKey int `json:"1number_key"`
OneNumberKey int64 `json:"1number_key"`
AvatarURL string `json:"avatar_url"`
Bio interface{} `json:"bio"`
Blog string `json:"blog"`
Company string `json:"company"`
CreatedAt string `json:"created_at"`
Email string `json:"email"`
EventsURL string `json:"events_url"`
Followers int `json:"followers"`
Followers int64 `json:"followers"`
FollowersURL string `json:"followers_url"`
Following int `json:"following"`
Following int64 `json:"following"`
FollowingURL string `json:"following_url"`
GistsURL string `json:"gists_url"`
GravatarID string `json:"gravatar_id"`
Hireable bool `json:"hireable"`
HTMLURL string `json:"html_url"`
ID int `json:"id"`
ID int64 `json:"id"`
Location string `json:"location"`
Login string `json:"login"`
Name string `json:"name"`
OrganizationsURL string `json:"organizations_url"`
PublicGists int `json:"public_gists"`
PublicRepos int `json:"public_repos"`
PublicGists int64 `json:"public_gists"`
PublicRepos int64 `json:"public_repos"`
ReceivedEventsURL string `json:"received_events_url"`
ReposURL string `json:"repos_url"`
StarredURL string `json:"starred_url"`
Expand Down
4 changes: 4 additions & 0 deletions examples/floats.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"count": 100,
"mean": 99.8
}
15 changes: 8 additions & 7 deletions gojson/gojson.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ import (
)

var (
name = flag.String("name", "Foo", "the name of the struct")
pkg = flag.String("pkg", "main", "the name of the package for the generated code")
inputName = flag.String("input", "", "the name of the input file containing JSON (if input not provided via STDIN)")
outputName = flag.String("o", "", "the name of the file to write the output to (outputs to STDOUT by default)")
format = flag.String("fmt", "json", "the format of the input data (json or yaml, defaults to json)")
tags = flag.String("tags", "fmt", "comma seperated list of the tags to put on the struct, default is the same as fmt")
subStruct = flag.Bool("subStruct", false, "create types for sub-structs (default is false)")
name = flag.String("name", "Foo", "the name of the struct")
pkg = flag.String("pkg", "main", "the name of the package for the generated code")
inputName = flag.String("input", "", "the name of the input file containing JSON (if input not provided via STDIN)")
outputName = flag.String("o", "", "the name of the file to write the output to (outputs to STDOUT by default)")
format = flag.String("fmt", "json", "the format of the input data (json or yaml, defaults to json)")
tags = flag.String("tags", "fmt", "comma seperated list of the tags to put on the struct, default is the same as fmt")
forceFloats = flag.Bool("forcefloats", false, "[experimental] force float64 type for integral values")
subStruct = flag.Bool("subStruct", false, "create types for sub-structs (default is false)")
)

func main() {
Expand Down
6 changes: 4 additions & 2 deletions json-to-struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ import (
"gopkg.in/yaml.v2"
)

var ForceFloats bool

// commonInitialisms is a set of common initialisms.
// Only add entries that are highly unlikely to be non-initialisms.
// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
Expand Down Expand Up @@ -499,8 +501,8 @@ func typeForValue(value interface{}, structName string, tags []string, subStruct
func disambiguateFloatInt(value interface{}) string {
const epsilon = .0001
vfloat := value.(float64)
if math.Abs(vfloat-math.Floor(vfloat+epsilon)) < epsilon {
var tmp int = 1
if !ForceFloats && math.Abs(vfloat-math.Floor(vfloat+epsilon)) < epsilon {
var tmp int64
return reflect.TypeOf(tmp).Name()
}
return reflect.TypeOf(value).Name()
Expand Down
50 changes: 50 additions & 0 deletions json-to-struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,56 @@ func TestInvalidFieldChars(t *testing.T) {
}
}

// TestDisambiguateFloatInt tests that disambiguateFloatInt correctly
// converts JSON numbers to the desired types.
func TestDisambiguateFloatInt(t *testing.T) {
examples := []struct {
FloatsOnly bool
In interface{}
Out string
}{
{FloatsOnly: false, In: 2.2, Out: "float64"},
{FloatsOnly: false, In: 2.0, Out: "int64"},
{FloatsOnly: false, In: float64(2), Out: "int64"},
{FloatsOnly: true, In: 2.2, Out: "float64"},
{FloatsOnly: true, In: 2.0, Out: "float64"},
{FloatsOnly: true, In: float64(2), Out: "float64"},
}

for i, ex := range examples {
ForceFloats = ex.FloatsOnly
if actual := disambiguateFloatInt(ex.In); actual != ex.Out {
t.Errorf("[Example %d] got %q, but expected %q", i+1, actual, ex.Out)
}
}
ForceFloats = false
}

// TestInferFloatInt tests that we can correctly disambiguate between
// a float and an int when no command-line flag is provided
func TestInferFloatInt(t *testing.T) {
f, err := os.Open(filepath.Join("examples", "floats.json"))
if err != nil {
t.Fatalf("error opening examples/floats.json: %s", err)
}
defer f.Close()

expected, err := ioutil.ReadFile(filepath.Join("examples", "expected_floats.go.out"))
if err != nil {
t.Fatalf("error reading expected_floats.go.out: %s", err)
}

actual, err := Generate(f, ParseJson, "Stats", "gojson", []string{"json"}, false)
if err != nil {
t.Error(err)
}
sactual, sexpected := string(actual), string(expected)
if sactual != sexpected {
t.Errorf("'%s' (expected) != '%s' (actual)", sexpected, sactual)
}

}

// Test example document
func TestExample(t *testing.T) {
i, err := os.Open(filepath.Join("examples", "example.json"))
Expand Down

0 comments on commit 6039f74

Please sign in to comment.