From 3e04114ae69a21dc27a554acb6ae568b046691d0 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 14 Jul 2023 21:28:44 +0300 Subject: [PATCH] replace interface{} with any The predeclared identifier 'any', an alias for the empty interface, is available as of Go 1.18. Use it in place of 'interface{}' since it's slightly shorter. GitHub-Pull-Request: https://github.com/shurcooL/graphql/pull/109 --- README.md | 4 ++-- example/graphqldev/main.go | 4 ++-- graphql.go | 12 ++++++------ graphql_test.go | 2 +- internal/jsonutil/graphql.go | 4 ++-- query.go | 10 +++++----- query_test.go | 38 ++++++++++++++++++------------------ scalar.go | 2 +- 8 files changed, 38 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index bf35325..d842768 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ var q struct { Then, define a `variables` map with their values: ```Go -variables := map[string]interface{}{ +variables := map[string]any{ "id": graphql.ID(id), "unit": starwars.LengthUnit("METER"), } @@ -252,7 +252,7 @@ var m struct { Commentary graphql.String } `graphql:"createReview(episode: $ep, review: $review)"` } -variables := map[string]interface{}{ +variables := map[string]any{ "ep": starwars.Episode("JEDI"), "review": starwars.ReviewInput{ Stars: graphql.Int(5), diff --git a/example/graphqldev/main.go b/example/graphqldev/main.go index bffb493..343c4d5 100644 --- a/example/graphqldev/main.go +++ b/example/graphqldev/main.go @@ -72,7 +72,7 @@ func run() error { AppearsIn []graphql.String } `graphql:"character(id: $characterID)"` } - variables := map[string]interface{}{ + variables := map[string]any{ "characterID": graphql.ID("1003"), } err = client.Query(context.Background(), &q, variables) @@ -85,7 +85,7 @@ func run() error { } // print pretty prints v to stdout. It panics on any error. -func print(v interface{}) { +func print(v any) { w := json.NewEncoder(os.Stdout) w.SetIndent("", "\t") err := w.Encode(v) diff --git a/graphql.go b/graphql.go index e516f75..38e92b7 100644 --- a/graphql.go +++ b/graphql.go @@ -32,19 +32,19 @@ func NewClient(url string, httpClient *http.Client) *Client { // Query executes a single GraphQL query request, // with a query derived from q, populating the response into it. // q should be a pointer to struct that corresponds to the GraphQL schema. -func (c *Client) Query(ctx context.Context, q interface{}, variables map[string]interface{}) error { +func (c *Client) Query(ctx context.Context, q any, variables map[string]any) error { return c.do(ctx, queryOperation, q, variables) } // Mutate executes a single GraphQL mutation request, // with a mutation derived from m, populating the response into it. // m should be a pointer to struct that corresponds to the GraphQL schema. -func (c *Client) Mutate(ctx context.Context, m interface{}, variables map[string]interface{}) error { +func (c *Client) Mutate(ctx context.Context, m any, variables map[string]any) error { return c.do(ctx, mutationOperation, m, variables) } // do executes a single GraphQL operation. -func (c *Client) do(ctx context.Context, op operationType, v interface{}, variables map[string]interface{}) error { +func (c *Client) do(ctx context.Context, op operationType, v any, variables map[string]any) error { var query string switch op { case queryOperation: @@ -53,8 +53,8 @@ func (c *Client) do(ctx context.Context, op operationType, v interface{}, variab query = constructMutation(v, variables) } in := struct { - Query string `json:"query"` - Variables map[string]interface{} `json:"variables,omitempty"` + Query string `json:"query"` + Variables map[string]any `json:"variables,omitempty"` }{ Query: query, Variables: variables, @@ -81,7 +81,7 @@ func (c *Client) do(ctx context.Context, op operationType, v interface{}, variab var out struct { Data *json.RawMessage Errors errors - //Extensions interface{} // Unused. + //Extensions any // Unused. } err = json.NewDecoder(resp.Body).Decode(&out) if err != nil { diff --git a/graphql_test.go b/graphql_test.go index 5b6de3b..95c5c2a 100644 --- a/graphql_test.go +++ b/graphql_test.go @@ -143,7 +143,7 @@ func TestClient_Query_emptyVariables(t *testing.T) { Name string } } - err := client.Query(context.Background(), &q, map[string]interface{}{}) + err := client.Query(context.Background(), &q, map[string]any{}) if err != nil { t.Fatal(err) } diff --git a/internal/jsonutil/graphql.go b/internal/jsonutil/graphql.go index b99a9e7..3b81d5c 100644 --- a/internal/jsonutil/graphql.go +++ b/internal/jsonutil/graphql.go @@ -17,7 +17,7 @@ import ( // // The implementation is created on top of the JSON tokenizer available // in "encoding/json".Decoder. -func UnmarshalGraphQL(data []byte, v interface{}) error { +func UnmarshalGraphQL(data []byte, v any) error { dec := json.NewDecoder(bytes.NewReader(data)) dec.UseNumber() err := (&decoder{tokenizer: dec}).Decode(v) @@ -57,7 +57,7 @@ type decoder struct { } // Decode decodes a single JSON value from d.tokenizer into v. -func (d *decoder) Decode(v interface{}) error { +func (d *decoder) Decode(v any) error { rv := reflect.ValueOf(v) if rv.Kind() != reflect.Ptr { return fmt.Errorf("cannot decode into non-pointer %T", v) diff --git a/query.go b/query.go index e10b771..6b1dd80 100644 --- a/query.go +++ b/query.go @@ -10,7 +10,7 @@ import ( "github.com/shurcooL/graphql/ident" ) -func constructQuery(v interface{}, variables map[string]interface{}) string { +func constructQuery(v any, variables map[string]any) string { query := query(v) if len(variables) > 0 { return "query(" + queryArguments(variables) + ")" + query @@ -18,7 +18,7 @@ func constructQuery(v interface{}, variables map[string]interface{}) string { return query } -func constructMutation(v interface{}, variables map[string]interface{}) string { +func constructMutation(v any, variables map[string]any) string { query := query(v) if len(variables) > 0 { return "mutation(" + queryArguments(variables) + ")" + query @@ -28,8 +28,8 @@ func constructMutation(v interface{}, variables map[string]interface{}) string { // queryArguments constructs a minified arguments string for variables. // -// E.g., map[string]interface{}{"a": Int(123), "b": NewBoolean(true)} -> "$a:Int!$b:Boolean". -func queryArguments(variables map[string]interface{}) string { +// E.g., map[string]any{"a": Int(123), "b": NewBoolean(true)} -> "$a:Int!$b:Boolean". +func queryArguments(variables map[string]any) string { // Sort keys in order to produce deterministic output for testing purposes. // TODO: If tests can be made to work with non-deterministic output, then no need to sort. keys := make([]string, 0, len(variables)) @@ -86,7 +86,7 @@ func writeArgumentType(w io.Writer, t reflect.Type, value bool) { // a minified query string from the provided struct v. // // E.g., struct{Foo Int, BarBaz *Boolean} -> "{foo,barBaz}". -func query(v interface{}) string { +func query(v any) string { var buf bytes.Buffer writeQuery(&buf, reflect.TypeOf(v), false) return buf.String() diff --git a/query_test.go b/query_test.go index 4de8cb5..b4f5af4 100644 --- a/query_test.go +++ b/query_test.go @@ -8,8 +8,8 @@ import ( func TestConstructQuery(t *testing.T) { tests := []struct { - inV interface{} - inVariables map[string]interface{} + inV any + inVariables map[string]any want string }{ { @@ -56,7 +56,7 @@ func TestConstructQuery(t *testing.T) { want: `{repository(owner:"shurcooL-test"name:"test-repo"){databaseId,url,issue(number:1){comments(first:1after:"Y3Vyc29yOjE5NTE4NDI1Ng=="){edges{node{body,author{login},editor{login}},cursor}}}}}`, }, { - inV: func() interface{} { + inV: func() any { type actor struct { Login String AvatarURL URI @@ -90,7 +90,7 @@ func TestConstructQuery(t *testing.T) { want: `{repository(owner:"shurcooL-test"name:"test-repo"){databaseId,url,issue(number:1){comments(first:1){edges{node{databaseId,author{login,avatarUrl,url},publishedAt,lastEditedAt,editor{login,avatarUrl,url},body,viewerCanUpdate},cursor}}}}}`, }, { - inV: func() interface{} { + inV: func() any { type actor struct { Login String AvatarURL URI `graphql:"avatarUrl(size:72)"` @@ -160,7 +160,7 @@ func TestConstructQuery(t *testing.T) { } `graphql:"issue(number: $issueNumber)"` } `graphql:"repository(owner: $repositoryOwner, name: $repositoryName)"` }{}, - inVariables: map[string]interface{}{ + inVariables: map[string]any{ "repositoryOwner": String("shurcooL-test"), "repositoryName": String("test-repo"), "issueNumber": Int(1), @@ -181,7 +181,7 @@ func TestConstructQuery(t *testing.T) { } `graphql:"issue(number: $issueNumber)"` } `graphql:"repository(owner: $repositoryOwner, name: $repositoryName)"` }{}, - inVariables: map[string]interface{}{ + inVariables: map[string]any{ "repositoryOwner": String("shurcooL-test"), "repositoryName": String("test-repo"), "issueNumber": Int(1), @@ -190,7 +190,7 @@ func TestConstructQuery(t *testing.T) { }, // Embedded structs without graphql tag should be inlined in query. { - inV: func() interface{} { + inV: func() any { type actor struct { Login String AvatarURL URI @@ -221,7 +221,7 @@ func TestConstructQuery(t *testing.T) { Viewer struct { Login string CreatedAt time.Time - ID interface{} + ID any DatabaseID int } }{}, @@ -238,8 +238,8 @@ func TestConstructQuery(t *testing.T) { func TestConstructMutation(t *testing.T) { tests := []struct { - inV interface{} - inVariables map[string]interface{} + inV any + inVariables map[string]any want string }{ { @@ -254,7 +254,7 @@ func TestConstructMutation(t *testing.T) { } } `graphql:"addReaction(input:$input)"` }{}, - inVariables: map[string]interface{}{ + inVariables: map[string]any{ "input": AddReactionInput{ SubjectID: "MDU6SXNzdWUyMzE1MjcyNzk=", Content: ReactionContentThumbsUp, @@ -273,44 +273,44 @@ func TestConstructMutation(t *testing.T) { func TestQueryArguments(t *testing.T) { tests := []struct { - in map[string]interface{} + in map[string]any want string }{ { - in: map[string]interface{}{"a": Int(123), "b": NewBoolean(true)}, + in: map[string]any{"a": Int(123), "b": NewBoolean(true)}, want: "$a:Int!$b:Boolean", }, { - in: map[string]interface{}{ + in: map[string]any{ "required": []IssueState{IssueStateOpen, IssueStateClosed}, "optional": &[]IssueState{IssueStateOpen, IssueStateClosed}, }, want: "$optional:[IssueState!]$required:[IssueState!]!", }, { - in: map[string]interface{}{ + in: map[string]any{ "required": []IssueState(nil), "optional": (*[]IssueState)(nil), }, want: "$optional:[IssueState!]$required:[IssueState!]!", }, { - in: map[string]interface{}{ + in: map[string]any{ "required": [...]IssueState{IssueStateOpen, IssueStateClosed}, "optional": &[...]IssueState{IssueStateOpen, IssueStateClosed}, }, want: "$optional:[IssueState!]$required:[IssueState!]!", }, { - in: map[string]interface{}{"id": ID("someID")}, + in: map[string]any{"id": ID("someID")}, want: "$id:ID!", }, { - in: map[string]interface{}{"ids": []ID{"someID", "anotherID"}}, + in: map[string]any{"ids": []ID{"someID", "anotherID"}}, want: `$ids:[ID!]!`, }, { - in: map[string]interface{}{"ids": &[]ID{"someID", "anotherID"}}, + in: map[string]any{"ids": &[]ID{"someID", "anotherID"}}, want: `$ids:[ID!]`, }, } diff --git a/scalar.go b/scalar.go index 0f7ceea..8679d34 100644 --- a/scalar.go +++ b/scalar.go @@ -23,7 +23,7 @@ type ( // intended to be human-readable. When expected as an input type, // any string (such as "VXNlci0xMA==") or integer (such as 4) input // value will be accepted as an ID. - ID interface{} + ID any // Int represents non-fractional signed whole numeric values. // Int can represent values between -(2^31) and 2^31 - 1.