Skip to content

Commit a2934cb

Browse files
committed
Generate structs for all used input types
1 parent 2d2a61c commit a2934cb

File tree

4 files changed

+60
-11
lines changed

4 files changed

+60
-11
lines changed

graphql_client_codegen/src/codegen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub(crate) fn response_for_query(
2727
generate_fragment_definitions(&operation, &all_used_types, &response_derives, options);
2828
let input_object_definitions =
2929
generate_input_object_definitions(&operation, &all_used_types, options);
30+
3031
let variables_struct = generate_variables_struct(&operation, options);
3132

3233
let definitions = render_response_data_fields(&operation, options).render(&response_derives);

graphql_client_codegen/src/resolution.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -826,9 +826,14 @@ impl<'a> VariableRef<'a> {
826826

827827
fn collect_used_types(&self, used_types: &mut UsedTypes) {
828828
match self.0.focus.1.r#type.id {
829-
type_id @ TypeId::Input(_)
830-
| type_id @ TypeId::Scalar(_)
831-
| type_id @ TypeId::Enum(_) => {
829+
TypeId::Input(input_id) => {
830+
used_types.types.insert(TypeId::Input(input_id));
831+
832+
let input = self.0.schema.input(input_id);
833+
834+
input.used_input_ids_recursive(used_types)
835+
}
836+
type_id @ TypeId::Scalar(_) | type_id @ TypeId::Enum(_) => {
832837
used_types.types.insert(type_id);
833838
}
834839
_ => (),
@@ -878,7 +883,7 @@ impl<'a> FragmentRef<'a> {
878883

879884
#[derive(Debug, Default)]
880885
pub(crate) struct UsedTypes {
881-
types: HashSet<TypeId>,
886+
pub(crate) types: HashSet<TypeId>,
882887
fragments: HashSet<ResolvedFragmentId>,
883888
}
884889

graphql_client_codegen/src/schema.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod graphql_parser_conversion;
22
mod json_conversion;
33

44
use crate::field_type::GraphqlTypeQualifier;
5+
use crate::resolution::UsedTypes;
56
use std::collections::HashMap;
67

78
#[derive(Clone, Copy)]
@@ -13,7 +14,6 @@ struct SchemaWith<'a, T> {
1314

1415
#[derive(Clone, Copy)]
1516
pub(crate) struct TypeRef<'a>(SchemaWith<'a, TypeId>);
16-
pub(crate) struct InputRef<'a>(SchemaWith<'a, InputId>);
1717

1818
pub(crate) const DEFAULT_SCALARS: &[&str] = &["ID", "String", "Int", "Float", "Boolean"];
1919

@@ -217,6 +217,13 @@ impl TypeId {
217217
}
218218
}
219219

220+
pub(crate) fn as_input_id(&self) -> Option<InputId> {
221+
match self {
222+
TypeId::Input(id) => Some(*id),
223+
_ => None,
224+
}
225+
}
226+
220227
pub(crate) fn as_scalar_id(&self) -> Option<ScalarId> {
221228
match self {
222229
TypeId::Scalar(id) => Some(*id),
@@ -266,7 +273,7 @@ struct StoredEnum {
266273
#[derive(Debug, Clone, PartialEq)]
267274
pub(crate) struct StoredInputFieldType {
268275
id: TypeId,
269-
pub(crate) qualifiers: Vec<GraphqlTypeQualifier>,
276+
qualifiers: Vec<GraphqlTypeQualifier>,
270277
}
271278

272279
impl StoredInputFieldType {
@@ -610,6 +617,8 @@ impl<'a> FieldRef<'a> {
610617
}
611618
}
612619

620+
pub(crate) struct InputRef<'a>(SchemaWith<'a, InputId>);
621+
613622
impl<'a> InputRef<'a> {
614623
fn get(&self) -> &'a StoredInputType {
615624
self.0.schema.get_stored_input(self.0.focus)
@@ -623,6 +632,30 @@ impl<'a> InputRef<'a> {
623632
&self.get().name
624633
}
625634

635+
pub(crate) fn used_input_ids_recursive<'b>(&'b self, used_types: &mut UsedTypes) {
636+
for input_id in self
637+
.fields()
638+
.map(|(_, type_id)| type_id)
639+
.filter_map(|type_id| type_id.as_input_id())
640+
{
641+
let type_id = TypeId::Input(input_id);
642+
if used_types.types.contains(&type_id) {
643+
continue;
644+
} else {
645+
used_types.types.insert(type_id);
646+
let input_ref = self.0.schema.input(input_id);
647+
input_ref.used_input_ids_recursive(used_types);
648+
}
649+
}
650+
}
651+
652+
pub(crate) fn fields<'b>(&'b self) -> impl Iterator<Item = (&'a str, TypeId)> + 'b {
653+
self.get()
654+
.fields
655+
.iter()
656+
.map(|(name, f)| (name.as_str(), f.id))
657+
}
658+
626659
pub(crate) fn contains_type_without_indirection(&self, type_name: &str) -> bool {
627660
todo!("contains type without indirection")
628661
// let input = self.get();

graphql_client_codegen/src/schema/graphql_parser_conversion.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InputId, Schema, TypeId};
1+
use super::{InputId, Schema, StoredInputFieldType, TypeId};
22
use crate::schema::resolve_field_type;
33
use graphql_parser::schema::{self as parser, Definition, Document, TypeDefinition, UnionType};
44

@@ -244,12 +244,22 @@ fn find_deprecation(directives: &[parser::Directive]) -> Option<Option<String>>
244244
}
245245

246246
fn ingest_input(schema: &mut Schema, input: &mut parser::InputObjectType) {
247-
let input_id = InputId::new(schema.stored_inputs.len());
248-
249-
// TODO: input object fields
250247
let input = super::StoredInputType {
251248
name: std::mem::replace(&mut input.name, String::new()),
252-
fields: Vec::new(),
249+
fields: input
250+
.fields
251+
.iter_mut()
252+
.map(|val| {
253+
let field_type = super::resolve_field_type(schema, &val.value_type);
254+
(
255+
std::mem::replace(&mut val.name, String::new()),
256+
StoredInputFieldType {
257+
qualifiers: field_type.qualifiers,
258+
id: field_type.id,
259+
},
260+
)
261+
})
262+
.collect(),
253263
};
254264

255265
schema.stored_inputs.push(input);

0 commit comments

Comments
 (0)