@@ -2,9 +2,10 @@ use super::shared::{field_rename_annotation, keyword_replace};
2
2
use crate :: {
3
3
codegen_options:: GraphQLClientCodegenOptions ,
4
4
query:: { BoundQuery , UsedTypes } ,
5
- schema:: input_is_recursive_without_indirection,
5
+ schema:: { input_is_recursive_without_indirection, StoredInputType } ,
6
+ type_qualifiers:: GraphqlTypeQualifier ,
6
7
} ;
7
- use heck:: ToSnakeCase ;
8
+ use heck:: { ToSnakeCase , ToUpperCamelCase } ;
8
9
use proc_macro2:: { Ident , Span , TokenStream } ;
9
10
use quote:: quote;
10
11
@@ -17,48 +18,112 @@ pub(super) fn generate_input_object_definitions(
17
18
all_used_types
18
19
. inputs ( query. schema )
19
20
. 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)
61
25
}
62
26
} )
63
27
. collect ( )
64
28
}
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