From fa720b845ea60581c489988f30d3ab201169b258 Mon Sep 17 00:00:00 2001 From: Cassio Conti Date: Thu, 29 Jul 2021 21:51:19 -0500 Subject: [PATCH] Support time types --- README.md | 36 +++++++++---------- examples/example_array.go.out | 4 +-- examples/expected_output_array_test.go.out | 4 +-- examples/expected_output_test.go.out | 4 +-- gojson/gojson.go | 4 +-- json-to-struct.go | 42 ++++++++++++---------- json-to-struct_test.go | 36 +++++++++++++++++++ 7 files changed, 86 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 7d88865..57e6e6b 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ type Repository struct { CompareURL string `json:"compare_url"` ContentsURL string `json:"contents_url"` ContributorsURL string `json:"contributors_url"` - CreatedAt string `json:"created_at"` + CreatedAt time.Time `json:"created_at"` DefaultBranch string `json:"default_branch"` Description string `json:"description"` DownloadsURL string `json:"downloads_url"` @@ -80,23 +80,23 @@ type Repository struct { Type string `json:"type"` URL string `json:"url"` } `json:"owner"` - Private bool `json:"private"` - PullsURL string `json:"pulls_url"` - PushedAt string `json:"pushed_at"` - Size float64 `json:"size"` - SshURL string `json:"ssh_url"` - StargazersURL string `json:"stargazers_url"` - StatusesURL string `json:"statuses_url"` - SubscribersURL string `json:"subscribers_url"` - SubscriptionURL string `json:"subscription_url"` - SvnURL string `json:"svn_url"` - TagsURL string `json:"tags_url"` - TeamsURL string `json:"teams_url"` - TreesURL string `json:"trees_url"` - UpdatedAt string `json:"updated_at"` - URL string `json:"url"` - Watchers float64 `json:"watchers"` - WatchersCount float64 `json:"watchers_count"` + Private bool `json:"private"` + PullsURL string `json:"pulls_url"` + PushedAt string `json:"pushed_at"` + Size float64 `json:"size"` + SshURL string `json:"ssh_url"` + StargazersURL string `json:"stargazers_url"` + StatusesURL string `json:"statuses_url"` + SubscribersURL string `json:"subscribers_url"` + SubscriptionURL string `json:"subscription_url"` + SvnURL string `json:"svn_url"` + TagsURL string `json:"tags_url"` + TeamsURL string `json:"teams_url"` + TreesURL string `json:"trees_url"` + UpdatedAt time.Time `json:"updated_at"` + URL string `json:"url"` + Watchers float64 `json:"watchers"` + WatchersCount float64 `json:"watchers_count"` } ``` diff --git a/examples/example_array.go.out b/examples/example_array.go.out index bc46dc9..2821b67 100644 --- a/examples/example_array.go.out +++ b/examples/example_array.go.out @@ -5,7 +5,7 @@ type Users []struct { Bio interface{} `json:"bio"` Blog string `json:"blog"` Company interface{} `json:"company"` - CreatedAt string `json:"created_at"` + CreatedAt time.Time `json:"created_at"` Email interface{} `json:"email"` EventsURL string `json:"events_url"` Followers int64 `json:"followers"` @@ -29,6 +29,6 @@ type Users []struct { StarredURL string `json:"starred_url"` SubscriptionsURL string `json:"subscriptions_url"` Type string `json:"type"` - UpdatedAt string `json:"updated_at"` + UpdatedAt time.Time `json:"updated_at"` URL string `json:"url"` } diff --git a/examples/expected_output_array_test.go.out b/examples/expected_output_array_test.go.out index 1c77d1d..9f9279f 100644 --- a/examples/expected_output_array_test.go.out +++ b/examples/expected_output_array_test.go.out @@ -10,7 +10,7 @@ type Users []struct { Bio interface{} `json:"bio"` Blog string `json:"blog"` Company string `json:"company"` - CreatedAt string `json:"created_at"` + CreatedAt time.Time `json:"created_at"` Email string `json:"email"` EventsURL string `json:"events_url"` Followers int64 `json:"followers"` @@ -33,6 +33,6 @@ type Users []struct { StarredURL string `json:"starred_url"` SubscriptionsURL string `json:"subscriptions_url"` Type string `json:"type"` - UpdatedAt string `json:"updated_at"` + UpdatedAt time.Time `json:"updated_at"` URL string `json:"url"` } diff --git a/examples/expected_output_test.go.out b/examples/expected_output_test.go.out index 76eb696..c18277f 100644 --- a/examples/expected_output_test.go.out +++ b/examples/expected_output_test.go.out @@ -6,7 +6,7 @@ type User struct { Bio interface{} `json:"bio"` Blog string `json:"blog"` Company string `json:"company"` - CreatedAt string `json:"created_at"` + CreatedAt time.Time `json:"created_at"` Email string `json:"email"` EventsURL string `json:"events_url"` Followers int64 `json:"followers"` @@ -29,6 +29,6 @@ type User struct { StarredURL string `json:"starred_url"` SubscriptionsURL string `json:"subscriptions_url"` Type string `json:"type"` - UpdatedAt string `json:"updated_at"` + UpdatedAt time.Time `json:"updated_at"` URL string `json:"url"` } diff --git a/gojson/gojson.go b/gojson/gojson.go index 7539aa5..45acdf1 100644 --- a/gojson/gojson.go +++ b/gojson/gojson.go @@ -13,7 +13,7 @@ // Bio interface{} `json:"bio"` // Blog string `json:"blog"` // Company string `json:"company"` -// CreatedAt string `json:"created_at"` +// CreatedAt time.Time `json:"created_at"` // Email string `json:"email"` // EventsURL string `json:"events_url"` // Followers float64 `json:"followers"` @@ -36,7 +36,7 @@ // StarredURL string `json:"starred_url"` // SubscriptionsURL string `json:"subscriptions_url"` // Type string `json:"type"` -// UpdatedAt string `json:"updated_at"` +// UpdatedAt time.Time `json:"updated_at"` // URL string `json:"url"` // } diff --git a/json-to-struct.go b/json-to-struct.go index 811ee71..10b4d7a 100644 --- a/json-to-struct.go +++ b/json-to-struct.go @@ -20,7 +20,7 @@ // CompareURL string `json:"compare_url"` // ContentsURL string `json:"contents_url"` // ContributorsURL string `json:"contributors_url"` -// CreatedAt string `json:"created_at"` +// CreatedAt time.Time `json:"created_at"` // DefaultBranch string `json:"default_branch"` // Description string `json:"description"` // DownloadsURL string `json:"downloads_url"` @@ -76,23 +76,23 @@ // Type string `json:"type"` // URL string `json:"url"` // } ` json:"owner"` -// Private bool `json:"private"` -// PullsURL string `json:"pulls_url"` -// PushedAt string `json:"pushed_at"` -// Size float64 `json:"size"` -// SshURL string `json:"ssh_url"` -// StargazersURL string `json:"stargazers_url"` -// StatusesURL string `json:"statuses_url"` -// SubscribersURL string `json:"subscribers_url"` -// SubscriptionURL string `json:"subscription_url"` -// SvnURL string `json:"svn_url"` -// TagsURL string `json:"tags_url"` -// TeamsURL string `json:"teams_url"` -// TreesURL string `json:"trees_url"` -// UpdatedAt string `json:"updated_at"` -// URL string `json:"url"` -// Watchers float64 `json:"watchers"` -// WatchersCount float64 `json:"watchers_count"` +// Private bool `json:"private"` +// PullsURL string `json:"pulls_url"` +// PushedAt string `json:"pushed_at"` +// Size float64 `json:"size"` +// SshURL string `json:"ssh_url"` +// StargazersURL string `json:"stargazers_url"` +// StatusesURL string `json:"statuses_url"` +// SubscribersURL string `json:"subscribers_url"` +// SubscriptionURL string `json:"subscription_url"` +// SvnURL string `json:"svn_url"` +// TagsURL string `json:"tags_url"` +// TeamsURL string `json:"teams_url"` +// TreesURL string `json:"trees_url"` +// UpdatedAt time.Time `json:"updated_at"` +// URL string `json:"url"` +// Watchers float64 `json:"watchers"` +// WatchersCount float64 `json:"watchers_count"` // } package gojson @@ -104,6 +104,7 @@ import ( "io" "math" "reflect" + "regexp" "sort" "strconv" "strings" @@ -491,6 +492,11 @@ func typeForValue(value interface{}, structName string, tags []string, subStruct v := reflect.TypeOf(value).Name() if v == "float64" && convertFloats { v = disambiguateFloatInt(value) + } else if v == "string" { + matched, err := regexp.MatchString(`\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?((\+|\-)\d{2}:\d{2}|Z)`, value.(string)) + if err == nil && matched { + v = "time.Time" + } } return v } diff --git a/json-to-struct_test.go b/json-to-struct_test.go index fe725e2..eaee98b 100644 --- a/json-to-struct_test.go +++ b/json-to-struct_test.go @@ -1,6 +1,7 @@ package gojson import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -159,3 +160,38 @@ func TestFmtFieldName(t *testing.T) { } } } + +func TestTime(t *testing.T) { + type testCase struct { + input string + expected string + } + + expectedTime := "package foopkg\n\ntype FooTime struct {\n\tCreatedTime time.Time `json:\"createdTime\"`\n}\n" + expectedString := "package foopkg\n\ntype FooTime struct {\n\tCreatedTime string `json:\"createdTime\"`\n}\n" + + testCases := []testCase{ + {"2021-07-28T12:34:56Z", expectedTime}, + {"2021-07-28T12:34:56", expectedString}, + {"2021-07-28T12:34:56.789Z", expectedTime}, + {"2021-07-28T12:34:56.789", expectedString}, + {"2021-07-28T12:34:56+06:00", expectedTime}, + {"2021-07-28T12:34:56-06:00", expectedTime}, + {"2021-07-28T12:34:56-0600", expectedString}, + {"2021-07-28T12:34:56.789-06:00", expectedTime}, + } + for _, test := range testCases { + t.Run(fmt.Sprintf("when time is %s", test.input), func(t *testing.T) { + jsonIn := fmt.Sprintf(`{"createdTime": "%s"}`, test.input) + bytes, err := Generate(strings.NewReader(jsonIn), ParseJson, "FooTime", "foopkg", []string{"json"}, false, true) + if err != nil { + t.Fatal(err) + } + + actual := string(bytes) + if test.expected != actual { + t.Fatalf("'%s' (expected) != '%s' (actual)", test.expected, actual) + } + }) + } +}