From 56cfc4900d0e4943bdc9953b8a8cc5465b567d1f Mon Sep 17 00:00:00 2001
From: Scott Lyons <scottalyons@gmail.com>
Date: Thu, 21 Dec 2023 15:22:17 -0800
Subject: [PATCH 1/2] Add custom name for `Other` variant

---
 graphql_client_codegen/src/codegen/enums.rs   | 15 +++++--
 graphql_client_codegen/src/codegen_options.rs | 15 ++++++-
 graphql_client_codegen/src/tests/mod.rs       | 45 ++++++++++++++++++-
 3 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/graphql_client_codegen/src/codegen/enums.rs b/graphql_client_codegen/src/codegen/enums.rs
index e990d02c..9c407943 100644
--- a/graphql_client_codegen/src/codegen/enums.rs
+++ b/graphql_client_codegen/src/codegen/enums.rs
@@ -59,18 +59,27 @@ pub(super) fn generate_enum_definitions<'a, 'schema: 'a>(
 
         let name = name_ident;
 
+        let fallback_name = if let Some(other_vname) = options.serde_enum_fallback_variant_name() {
+            other_vname.to_owned()
+        } else {
+            "Other".to_string()
+        };
+
+        let fallback_ident = Ident::new(&fallback_name, Span::call_site());
+        let fallback_variant =  quote!(#fallback_ident);
+
         quote! {
             #derives
             pub enum #name {
                 #(#variant_names,)*
-                Other(String),
+                #fallback_variant(String)
             }
 
             impl ::serde::Serialize for #name {
                 fn serialize<S: serde::Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
                     ser.serialize_str(match *self {
                         #(#constructors => #variant_str,)*
-                        #name::Other(ref s) => &s,
+                        #name::#fallback_variant(ref s) => &s,
                     })
                 }
             }
@@ -81,7 +90,7 @@ pub(super) fn generate_enum_definitions<'a, 'schema: 'a>(
 
                     match s.as_str() {
                         #(#variant_str => Ok(#constructors),)*
-                        _ => Ok(#name::Other(s)),
+                        _ => Ok(#name::#fallback_variant(s)),
                     }
                 }
             }
diff --git a/graphql_client_codegen/src/codegen_options.rs b/graphql_client_codegen/src/codegen_options.rs
index 164b0dd7..672f2024 100644
--- a/graphql_client_codegen/src/codegen_options.rs
+++ b/graphql_client_codegen/src/codegen_options.rs
@@ -45,8 +45,10 @@ pub struct GraphQLClientCodegenOptions {
     extern_enums: Vec<String>,
     /// Flag to trigger generation of Other variant for fragments Enum
     fragments_other_variant: bool,
+    /// Create Other variant with custom name for ser/de
+    serde_enum_fallback_variant_name: Option<String>,
     /// Skip Serialization of None values.
-    skip_serializing_none: bool,
+    skip_serializing_none: bool
 }
 
 impl GraphQLClientCodegenOptions {
@@ -67,6 +69,7 @@ impl GraphQLClientCodegenOptions {
             custom_scalars_module: Default::default(),
             extern_enums: Default::default(),
             fragments_other_variant: Default::default(),
+            serde_enum_fallback_variant_name: Default::default(),
             skip_serializing_none: Default::default(),
         }
     }
@@ -218,6 +221,16 @@ impl GraphQLClientCodegenOptions {
         &self.fragments_other_variant
     }
 
+    /// Set the graphql client codegen option's serde_enum_fallback_variant_name
+    pub fn set_serde_enum_fallback_variant_name(&mut self, serde_enum_fallback_variant_name: Option<String>) {
+        self.serde_enum_fallback_variant_name = serde_enum_fallback_variant_name;
+    }
+
+    /// Get a reference to the graphql client codegen option's serde_enum_fallback_variant_name
+    pub fn serde_enum_fallback_variant_name(&self) -> &Option<String> {
+        &self.serde_enum_fallback_variant_name
+    }
+
     /// Set the graphql client codegen option's skip none value.
     pub fn set_skip_serializing_none(&mut self, skip_serializing_none: bool) {
         self.skip_serializing_none = skip_serializing_none
diff --git a/graphql_client_codegen/src/tests/mod.rs b/graphql_client_codegen/src/tests/mod.rs
index b80ba5d2..da682e3e 100644
--- a/graphql_client_codegen/src/tests/mod.rs
+++ b/graphql_client_codegen/src/tests/mod.rs
@@ -64,7 +64,7 @@ fn fragments_other_variant_should_generate_unknown_other_variant() {
         .to_token_stream()
         .expect("Generate foobars module");
         let generated_code = generated_tokens.to_string();
-
+        
         let r: syn::parse::Result<proc_macro2::TokenStream> = syn::parse2(generated_tokens);
         match r {
             Ok(_) => {
@@ -159,3 +159,46 @@ fn skip_serializing_none_should_generate_serde_skip_serializing() {
         };
     }
 }
+
+#[test]
+fn serde_enum_custom_fallback_name() {
+    let query_string = include_str!("keywords_query.graphql");
+    let query = graphql_parser::parse_query::<&str>(query_string).expect("Parse keywords query");
+    let schema = graphql_parser::parse_schema(include_str!("keywords_schema.graphql"))
+        .expect("Parse keywords schema")
+        .into_static();
+    let schema = Schema::from(schema);
+
+    let mut options = GraphQLClientCodegenOptions::new(CodegenMode::Cli);
+
+    options.set_serde_enum_fallback_variant_name(Some("Autre".to_string()));
+
+    let query = crate::query::resolve(&schema, &query).unwrap();
+
+    for (_id, operation) in query.operations() {
+        let generated_tokens = generated_module::GeneratedModule {
+            query_string,
+            schema: &schema,
+            operation: &operation.name,
+            resolved_query: &query,
+            options: &options,
+        }
+        .to_token_stream()
+        .expect("Generate keywords module");
+
+        let generated_code = generated_tokens.to_string();
+
+        let r: syn::parse::Result<proc_macro2::TokenStream> = syn::parse2(generated_tokens);
+
+        match r {
+            Ok(_) => {
+                println!("{}", generated_code);
+                assert!(!generated_code.contains("Other (String)"));
+                assert!(generated_code.contains("Autre (String)"));
+            }
+            Err(e) => {
+                panic!("Error: {}\n Generated content: {}\n", e, &generated_code);
+            }
+        };
+    }
+}
\ No newline at end of file

From 4be6d215801c3b87415dcd8ea140ef6825779528 Mon Sep 17 00:00:00 2001
From: Scott Lyons <scottalyons@gmail.com>
Date: Thu, 21 Dec 2023 15:34:26 -0800
Subject: [PATCH 2/2] Definitely didn't forget to add it to the attr options

---
 graphql_query_derive/src/lib.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/graphql_query_derive/src/lib.rs b/graphql_query_derive/src/lib.rs
index f335aa79..e0b14cdb 100644
--- a/graphql_query_derive/src/lib.rs
+++ b/graphql_query_derive/src/lib.rs
@@ -64,11 +64,13 @@ fn build_graphql_client_derive_options(
     let custom_scalars_module = attributes::extract_attr(input, "custom_scalars_module").ok();
     let extern_enums = attributes::extract_attr_list(input, "extern_enums").ok();
     let fragments_other_variant: bool = attributes::extract_fragments_other_variant(input);
+    let serde_enum_fallback_variant_name: Option<String> = attributes::extract_attr(input, "serde_enum_fallback_variant_name").ok();
     let skip_serializing_none: bool = attributes::extract_skip_serializing_none(input);
 
     let mut options = GraphQLClientCodegenOptions::new(CodegenMode::Derive);
     options.set_query_file(query_path);
     options.set_fragments_other_variant(fragments_other_variant);
+    options.set_serde_enum_fallback_variant_name(serde_enum_fallback_variant_name);
     options.set_skip_serializing_none(skip_serializing_none);
 
     if let Some(variables_derives) = variables_derives {