graphql-rust/graphql-client

Unable to derive from the GraphQLQuery Macro - Expected String but got &str

imjacobclark opened this issue · 2 comments

Unable to derive from the GraphQLQuery Macro

Issue:

use graphql_client::{GraphQLQuery};
#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "src/graphql/github_schema.graphql",
    query_path = "src/graphql/queries/QueryPullRequestData.graphql",
    response_derives = "Debug"
)]

pub struct GetRepositories; 

Error:

imjacobclark@mutt:~/workspace/flow/ingestor$ cargo run
   Compiling ingestor v0.1.0 (/home/imjacobclark/workspace/flow/ingestor)
error[E0308]: mismatched types
   --> ingestor/src/main.rs:18:10
    |
18  | #[derive(GraphQLQuery)]
    |          ^^^^^^^^^^^^
    |          |
    |          expected `String`, found `&str`
    |          arguments to this enum variant are incorrect

I tried to resolve in the following ways:

use graphql_client::{GraphQLQuery};
#[derive(GraphQLQuery)]
#[graphql(
    schema_path = String::from("src/graphql/github_schema.graphql"),
    query_path = String::from("src/graphql/queries/QueryPullRequestData.graphql"),
    response_derives = String::from("Debug"),
)]

pub struct GetRepositories; 

Error:

imjacobclark@mutt:~/workspace/flow/ingestor$ cargo run
   Compiling ingestor v0.1.0 (/home/imjacobclark/workspace/flow/ingestor)
error: proc-macro derive panicked
  --> ingestor/src/main.rs:18:10
   |
18 | #[derive(GraphQLQuery)]
   |          ^^^^^^^^^^^^
   |
   = help: message: Attribute is well formatted: Error("expected literal")

error: could not compile `ingestor` (bin "ingestor") due to 1 previous error

Versions:

graphql_client = "0.14.0"
imjacobclark@mutt:~/workspace/flow/ingestor$ rustc --version
rustc 1.83.0 (90b35a623 2024-11-26)

Hi, don't have a direct answer but just learned something closely related. This might help your problem. Also posting here for others to find.

Likely bug with code generation for enum defaults

I was getting similar errors to those above. There is likely a code generation bug relating to enums and defaults. Issue seems to be that codegen from GQL dumps for a query's enum input defaults a string and not the newly generated native enum type. This results in errors such as yours (e.g. Expected String but got &str or Expected _EnumSomething_ but got &str).

More precisely, the generated code for query input default (if is an enum) gets generated as e.g. "MyQuery_enumval" but not the type correct my_query::enumval. I found the bug by looking at code generate output graphql-client generate [FLAGS] [OPTIONS] <query_path> --schema-path <schema_path>. I wasted a lot of time trying to find the answer in the schema.

Pseudo example:

This fails (MyQuery.graphql)

query MyQuery(
  $foo: Enum1 = EnumDefault
) {
...
}

This Works with graphql-client

query MyQuery(
  $foo: Enum1
) {
...
}

and accessing the value in code via my_query::Enum_.

This is all being done with the familiar derive:

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "src/schema.json",
    query_path = "src/gql/MyQuery.gql",
    response_derives = "Debug"
)]
pub struct MyQuery;

PS, I was really struggling to find this since the solution was hidden behind another error when using MyQuery::Enum1 requiring a complete path to trait suggestion e.g. <MyQuery as Example>::Enum1. This suggestion was very misleading until I finally figured out what was going on. I was getting confused between case of the struct MyQuery:: vs. what I should have been using was the module my_query::Enum1.

graphql-client = "^0.14"
rust = 1.82

Thanks for reporting! Definitely something to fix.