graphql-rust / graphql-client

Typed, correct GraphQL requests and responses in Rust
Apache License 2.0
1.15k stars 158 forks source link

Nested variable renaming uses camel case instead of snake case #386

Open bragaigor opened 3 years ago

bragaigor commented 3 years ago

Hello, recently I've upgraded graphql-client version from 0.9.0 to 0.10.0 and the variable renaming of nested structs defined in graphql does not rename the variables using camel case anymore. I apologize for the code dump but I think it would be best if I showed what I mean.

Say I have the following struct defined:

#[derive(juniper::GraphQLInputObject, Clone, Validate, Serialize, Deserialize)]
pub struct Actor {
    pub first_name: String,
    pub last_name: String,
}

From which I can generate a schema.json file which would contain the following:

...
{
        "kind": "INPUT_OBJECT",
        "name": "Actor",
        "description": "",
        "fields": null,
        "inputFields": [
          {
            "name": "firstName",
            "description": "",
            "type": {
              "kind": "NON_NULL",
              "name": null,
              "ofType": {
                "kind": "SCALAR",
                "name": "String",
                "ofType": null
              }
            },
            "defaultValue": null
          },
          {
            "name": "lastName",
            "description": "",
            "type": {
              "kind": "SCALAR",
              "name": "String",
              "ofType": null
            },
            "defaultValue": null
          },
        ],
        "interfaces": null,
        "enumValues": null,
        "possibleTypes": null
      },
...

I also have created a file query.graphql to contain the target query to be tested:

mutation ActorCreation ($movieName:String!, $actor:Actor!) {
  createActor(movieName:$movie, actor:$actor) {
    firstName
    lastName
    movie
  }
}

And somewhere in my rust code I need to build the input for mutation ActorCreation, something like:

    #[derive(GraphQLQuery, Copy, Clone, PartialEq)]
    #[graphql(
        schema_path = "schema.json",
        query_path = "src/tests/query.graphql",
        response_derives = "Debug, PartialEq",
        normalization = "rust"
    )]
    struct ActorCreation;
    ...
    let query: QueryBody<actor_creation::Variables> =
        ActorCreation::build_query(actor_creation::Variables {
            movie_name: "Star Wars",
            actor: actor_creation::Actor {
                first_name: "Adam".to_string(), // <<<<<<<<<<<<< ERROR
                last_name: "Driver".to_string(), // <<<<<<<<<<<< ERROR
            },
        });
    ...   

The errors being:

error[E0560]: struct `actor_creation::Actor` has no field named `first_name`
   --> /tests/test.rs:811:21
    |
811 |                     first_name: "Adam".to_string(),
    |                     ^^^^^^^^ help: a field with a similar name exists: `firstName`

error[E0560]: struct `actor_creation::Actor` has no field named `last_name`
   --> /tests/test.rs:812:21
    |
812 |                     last_name: "Driver".to_string(),
    |                     ^^^^^^^^^ help: a field with a similar name exists: `lastName`

error: aborting due to 2 previous errors

Instead with version 0.10.0 I'm having to do the following with camel case:

...
            ActorCreation::build_query(actor_creation::Variables {
                movie_name: "Star Wars",
                actor: actor_creation::Actor {
                    firstName: "Adam".to_string(), // <<<<<<<<<<<<< HAPPY
                    lastName: "Driver".to_string(), // <<<<<<<<<<<< HAPPY
                },
            });

I spent some time looking for a way to generate the snake case variables but all I could find was the attribute normalization but that did not quite work. Am I missing something, or is there a way to make this happen?

Thank you in advance!

tomhoule commented 3 years ago

Thanks for the report! It looks like a bug to be fixed, indeed.

bragaigor commented 3 years ago

My pleasure!