@@ -2,9 +2,10 @@ use super::shared::{field_rename_annotation, keyword_replace};
22use crate :: {
33 codegen_options:: GraphQLClientCodegenOptions ,
44 query:: { BoundQuery , UsedTypes } ,
5- schema:: input_is_recursive_without_indirection,
5+ schema:: { input_is_recursive_without_indirection, StoredInputType } ,
6+ type_qualifiers:: GraphqlTypeQualifier ,
67} ;
7- use heck:: ToSnakeCase ;
8+ use heck:: { ToSnakeCase , ToUpperCamelCase } ;
89use proc_macro2:: { Ident , Span , TokenStream } ;
910use quote:: quote;
1011
@@ -17,48 +18,112 @@ pub(super) fn generate_input_object_definitions(
1718 all_used_types
1819 . inputs ( query. schema )
1920 . map ( |( _input_id, input) | {
20- let normalized_name = options. normalization ( ) . input_name ( input. name . as_str ( ) ) ;
21- let safe_name = keyword_replace ( normalized_name) ;
22- let struct_name = Ident :: new ( safe_name. as_ref ( ) , Span :: call_site ( ) ) ;
23-
24- let fields = input. fields . iter ( ) . map ( |( field_name, field_type) | {
25- let safe_field_name = keyword_replace ( field_name. to_snake_case ( ) ) ;
26- let annotation = field_rename_annotation ( field_name, safe_field_name. as_ref ( ) ) ;
27- let name_ident = Ident :: new ( safe_field_name. as_ref ( ) , Span :: call_site ( ) ) ;
28- let normalized_field_type_name = options
29- . normalization ( )
30- . field_type ( field_type. id . name ( query. schema ) ) ;
31- let optional_skip_serializing_none =
32- if * options. skip_serializing_none ( ) && field_type. is_optional ( ) {
33- Some ( quote ! ( #[ serde( skip_serializing_if = "Option::is_none" ) ] ) )
34- } else {
35- None
36- } ;
37- let type_name = Ident :: new ( normalized_field_type_name. as_ref ( ) , Span :: call_site ( ) ) ;
38- let field_type_tokens = super :: decorate_type ( & type_name, & field_type. qualifiers ) ;
39- let field_type = if field_type
40- . id
41- . as_input_id ( )
42- . map ( |input_id| input_is_recursive_without_indirection ( input_id, query. schema ) )
43- . unwrap_or ( false )
44- {
45- quote ! ( Box <#field_type_tokens>)
46- } else {
47- field_type_tokens
48- } ;
49-
50- quote ! (
51- #optional_skip_serializing_none
52- #annotation pub #name_ident: #field_type
53- )
54- } ) ;
55-
56- quote ! {
57- #variable_derives
58- pub struct #struct_name{
59- #( #fields, ) *
60- }
21+ if input. is_one_of {
22+ generate_enum ( input, options, variable_derives, query)
23+ } else {
24+ generate_struct ( input, options, variable_derives, query)
6125 }
6226 } )
6327 . collect ( )
6428}
29+
30+ fn generate_struct (
31+ input : & StoredInputType ,
32+ options : & GraphQLClientCodegenOptions ,
33+ variable_derives : & impl quote:: ToTokens ,
34+ query : & BoundQuery < ' _ > ,
35+ ) -> TokenStream {
36+ let normalized_name = options. normalization ( ) . input_name ( input. name . as_str ( ) ) ;
37+ let safe_name = keyword_replace ( normalized_name) ;
38+ let struct_name = Ident :: new ( safe_name. as_ref ( ) , Span :: call_site ( ) ) ;
39+
40+ let fields = input. fields . iter ( ) . map ( |( field_name, field_type) | {
41+ let safe_field_name = keyword_replace ( field_name. to_snake_case ( ) ) ;
42+ let annotation = field_rename_annotation ( field_name, safe_field_name. as_ref ( ) ) ;
43+ let name_ident = Ident :: new ( safe_field_name. as_ref ( ) , Span :: call_site ( ) ) ;
44+ let normalized_field_type_name = options
45+ . normalization ( )
46+ . field_type ( field_type. id . name ( query. schema ) ) ;
47+ let optional_skip_serializing_none =
48+ if * options. skip_serializing_none ( ) && field_type. is_optional ( ) {
49+ Some ( quote ! ( #[ serde( skip_serializing_if = "Option::is_none" ) ] ) )
50+ } else {
51+ None
52+ } ;
53+ let type_name = Ident :: new ( normalized_field_type_name. as_ref ( ) , Span :: call_site ( ) ) ;
54+ let field_type_tokens = super :: decorate_type ( & type_name, & field_type. qualifiers ) ;
55+ let field_type = if field_type
56+ . id
57+ . as_input_id ( )
58+ . map ( |input_id| input_is_recursive_without_indirection ( input_id, query. schema ) )
59+ . unwrap_or ( false )
60+ {
61+ quote ! ( Box <#field_type_tokens>)
62+ } else {
63+ field_type_tokens
64+ } ;
65+
66+ quote ! (
67+ #optional_skip_serializing_none
68+ #annotation pub #name_ident: #field_type
69+ )
70+ } ) ;
71+
72+ quote ! {
73+ #variable_derives
74+ pub struct #struct_name{
75+ #( #fields, ) *
76+ }
77+ }
78+ }
79+
80+ fn generate_enum (
81+ input : & StoredInputType ,
82+ options : & GraphQLClientCodegenOptions ,
83+ variable_derives : & impl quote:: ToTokens ,
84+ query : & BoundQuery < ' _ > ,
85+ ) -> TokenStream {
86+ let normalized_name = options. normalization ( ) . input_name ( input. name . as_str ( ) ) ;
87+ let safe_name = keyword_replace ( normalized_name) ;
88+ let enum_name = Ident :: new ( safe_name. as_ref ( ) , Span :: call_site ( ) ) ;
89+
90+ let variants = input. fields . iter ( ) . map ( |( field_name, field_type) | {
91+ let variant_name = field_name. to_upper_camel_case ( ) ;
92+ let safe_variant_name = keyword_replace ( & variant_name) ;
93+
94+ let annotation = field_rename_annotation ( field_name. as_ref ( ) , & variant_name) ;
95+ let name_ident = Ident :: new ( safe_variant_name. as_ref ( ) , Span :: call_site ( ) ) ;
96+
97+ let normalized_field_type_name = options
98+ . normalization ( )
99+ . field_type ( field_type. id . name ( query. schema ) ) ;
100+ let type_name = Ident :: new ( normalized_field_type_name. as_ref ( ) , Span :: call_site ( ) ) ;
101+
102+ // Add the required qualifier so that the variant's field isn't wrapped in Option
103+ let mut qualifiers = vec ! [ GraphqlTypeQualifier :: Required ] ;
104+ qualifiers. extend ( field_type. qualifiers . iter ( ) . cloned ( ) ) ;
105+
106+ let field_type_tokens = super :: decorate_type ( & type_name, & qualifiers) ;
107+ let field_type = if field_type
108+ . id
109+ . as_input_id ( )
110+ . map ( |input_id| input_is_recursive_without_indirection ( input_id, query. schema ) )
111+ . unwrap_or ( false )
112+ {
113+ quote ! ( Box <#field_type_tokens>)
114+ } else {
115+ field_type_tokens
116+ } ;
117+
118+ quote ! (
119+ #annotation #name_ident( #field_type)
120+ )
121+ } ) ;
122+
123+ quote ! {
124+ #variable_derives
125+ pub enum #enum_name{
126+ #( #variants, ) *
127+ }
128+ }
129+ }
0 commit comments