From 4e94b620ffe41a5c88a43ff6c93be17ca3d56967 Mon Sep 17 00:00:00 2001 From: Graeme Coupar Date: Mon, 14 Oct 2024 11:19:15 +0100 Subject: [PATCH] feat: refactor IdReader APIs in parser (#1064) #### Why are we making this change? The `IdReader` API used to rely on the implementation of `TypeSystemId`/`ExecutableApi` to create Readers. This meant that working with this in a generic way had some quite complicated trait bounds, and also means that an `Id` can only be associated with one kind of `Reader`. #### What effects does this change have? Adds a `new` function into the `IdReader` api which simplifies the trait bounds and also allows multiple `Readers` to use the same `Id` should they want to. --- cynic-parser/ast-generator/src/object.rs | 6 ++- cynic-parser/ast-generator/src/union.rs | 6 ++- .../src/executable/generated/argument.rs | 5 +- .../src/executable/generated/definition.rs | 5 +- .../src/executable/generated/directive.rs | 5 +- .../src/executable/generated/fragment.rs | 5 +- .../src/executable/generated/operation.rs | 5 +- .../src/executable/generated/selections.rs | 20 ++++++-- .../src/executable/generated/variable.rs | 5 +- cynic-parser/src/executable/iter.rs | 32 ++++++------ .../src/printing/display/executable.rs | 8 +-- .../pretty/type_system/field_sequence.rs | 19 ++++--- cynic-parser/src/type_system/definitions.rs | 6 ++- .../src/type_system/generated/arguments.rs | 5 +- .../src/type_system/generated/descriptions.rs | 5 +- .../src/type_system/generated/directives.rs | 10 +++- .../src/type_system/generated/enums.rs | 10 +++- .../src/type_system/generated/fields.rs | 5 +- .../type_system/generated/input_objects.rs | 5 +- .../src/type_system/generated/input_values.rs | 5 +- .../src/type_system/generated/interfaces.rs | 5 +- .../src/type_system/generated/name.rs | 49 +++++++++++++++++++ .../src/type_system/generated/objects.rs | 5 +- .../src/type_system/generated/scalars.rs | 5 +- .../src/type_system/generated/schemas.rs | 10 +++- .../src/type_system/generated/unions.rs | 10 +++- cynic-parser/src/type_system/iter.rs | 26 +++++----- 27 files changed, 212 insertions(+), 70 deletions(-) create mode 100644 cynic-parser/src/type_system/generated/name.rs diff --git a/cynic-parser/ast-generator/src/object.rs b/cynic-parser/ast-generator/src/object.rs index 8d61ebbb..831901a5 100644 --- a/cynic-parser/ast-generator/src/object.rs +++ b/cynic-parser/ast-generator/src/object.rs @@ -86,8 +86,12 @@ pub fn object_output( })?; let id_reader_impl = format_code(quote! { - impl IdReader for #reader_name<'_> { + impl<'a> IdReader<'a> for #reader_name<'a> { type Id = #id_name; + + fn new(id: Self::Id, document: &'a #document_type) -> Self { + document.read(id) + } } })?; diff --git a/cynic-parser/ast-generator/src/union.rs b/cynic-parser/ast-generator/src/union.rs index c253bb1a..b1b3bee3 100644 --- a/cynic-parser/ast-generator/src/union.rs +++ b/cynic-parser/ast-generator/src/union.rs @@ -76,8 +76,12 @@ pub fn union_output( })?; let id_reader_impl = format_code(quote! { - impl IdReader for #reader_name<'_> { + impl<'a> IdReader<'a> for #reader_name<'a> { type Id = #id_name; + + fn new(id: Self::Id, document: &'a #document_type) -> Self { + document.read(id) + } } })?; diff --git a/cynic-parser/src/executable/generated/argument.rs b/cynic-parser/src/executable/generated/argument.rs index 17c845e2..c9ddd3a7 100644 --- a/cynic-parser/src/executable/generated/argument.rs +++ b/cynic-parser/src/executable/generated/argument.rs @@ -48,6 +48,9 @@ impl ExecutableId for ArgumentId { } } -impl IdReader for Argument<'_> { +impl<'a> IdReader<'a> for Argument<'a> { type Id = ArgumentId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/executable/generated/definition.rs b/cynic-parser/src/executable/generated/definition.rs index 8205b144..bfd7cd17 100644 --- a/cynic-parser/src/executable/generated/definition.rs +++ b/cynic-parser/src/executable/generated/definition.rs @@ -33,6 +33,9 @@ impl ExecutableId for ExecutableDefinitionId { } } -impl IdReader for ExecutableDefinition<'_> { +impl<'a> IdReader<'a> for ExecutableDefinition<'a> { type Id = ExecutableDefinitionId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/executable/generated/directive.rs b/cynic-parser/src/executable/generated/directive.rs index 66f5602e..aaa30300 100644 --- a/cynic-parser/src/executable/generated/directive.rs +++ b/cynic-parser/src/executable/generated/directive.rs @@ -48,6 +48,9 @@ impl ExecutableId for DirectiveId { } } -impl IdReader for Directive<'_> { +impl<'a> IdReader<'a> for Directive<'a> { type Id = DirectiveId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/executable/generated/fragment.rs b/cynic-parser/src/executable/generated/fragment.rs index 8a5cabe6..f9f17460 100644 --- a/cynic-parser/src/executable/generated/fragment.rs +++ b/cynic-parser/src/executable/generated/fragment.rs @@ -61,6 +61,9 @@ impl ExecutableId for FragmentDefinitionId { } } -impl IdReader for FragmentDefinition<'_> { +impl<'a> IdReader<'a> for FragmentDefinition<'a> { type Id = FragmentDefinitionId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/executable/generated/operation.rs b/cynic-parser/src/executable/generated/operation.rs index 31addf99..aeb5e8b8 100644 --- a/cynic-parser/src/executable/generated/operation.rs +++ b/cynic-parser/src/executable/generated/operation.rs @@ -71,6 +71,9 @@ impl ExecutableId for OperationDefinitionId { } } -impl IdReader for OperationDefinition<'_> { +impl<'a> IdReader<'a> for OperationDefinition<'a> { type Id = OperationDefinitionId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/executable/generated/selections.rs b/cynic-parser/src/executable/generated/selections.rs index 370b4fde..2797bc3a 100644 --- a/cynic-parser/src/executable/generated/selections.rs +++ b/cynic-parser/src/executable/generated/selections.rs @@ -34,8 +34,11 @@ impl ExecutableId for SelectionId { } } -impl IdReader for Selection<'_> { +impl<'a> IdReader<'a> for Selection<'a> { type Id = SelectionId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } pub struct FieldSelectionRecord { @@ -100,8 +103,11 @@ impl ExecutableId for FieldSelectionId { } } -impl IdReader for FieldSelection<'_> { +impl<'a> IdReader<'a> for FieldSelection<'a> { type Id = FieldSelectionId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } pub struct InlineFragmentRecord { @@ -154,8 +160,11 @@ impl ExecutableId for InlineFragmentId { } } -impl IdReader for InlineFragment<'_> { +impl<'a> IdReader<'a> for InlineFragment<'a> { type Id = InlineFragmentId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } pub struct FragmentSpreadRecord { @@ -199,6 +208,9 @@ impl ExecutableId for FragmentSpreadId { } } -impl IdReader for FragmentSpread<'_> { +impl<'a> IdReader<'a> for FragmentSpread<'a> { type Id = FragmentSpreadId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/executable/generated/variable.rs b/cynic-parser/src/executable/generated/variable.rs index 1592313e..88255aaa 100644 --- a/cynic-parser/src/executable/generated/variable.rs +++ b/cynic-parser/src/executable/generated/variable.rs @@ -65,6 +65,9 @@ impl ExecutableId for VariableDefinitionId { } } -impl IdReader for VariableDefinition<'_> { +impl<'a> IdReader<'a> for VariableDefinition<'a> { type Id = VariableDefinitionId; + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/executable/iter.rs b/cynic-parser/src/executable/iter.rs index 4b675a39..7abf3e22 100644 --- a/cynic-parser/src/executable/iter.rs +++ b/cynic-parser/src/executable/iter.rs @@ -2,10 +2,12 @@ use std::{fmt, iter::FusedIterator}; use crate::common::{IdOperations, IdRange, IdRangeIter}; -use super::ExecutableId; +use super::{ExecutableDocument, ExecutableId}; -pub trait IdReader { +pub trait IdReader<'a> { type Id: ExecutableId; + + fn new(id: Self::Id, document: &'a ExecutableDocument) -> Self; } /// Iterator for readers in the executable module @@ -14,7 +16,7 @@ pub trait IdReader { #[derive(Clone)] pub struct Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, { ids: IdRangeIter, document: &'a super::ExecutableDocument, @@ -22,7 +24,7 @@ where impl<'a, T> Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, { pub(crate) fn new(range: IdRange, document: &'a super::ExecutableDocument) -> Self where @@ -50,7 +52,7 @@ where impl<'a, T> Iterator for Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { type Item = ::Reader<'a>; @@ -66,21 +68,21 @@ where impl<'a, T> ExactSizeIterator for Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { } impl<'a, T> FusedIterator for Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { } impl<'a, T> DoubleEndedIterator for Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { // Required method @@ -91,7 +93,7 @@ where impl<'a, T> fmt::Debug for Iter<'a, T> where - T: IdReader + Copy, + T: IdReader<'a> + Copy, Self: Iterator, ::Item: fmt::Debug, { @@ -106,7 +108,7 @@ where #[derive(Clone)] pub struct IdIter<'a, T> where - T: IdReader, + T: IdReader<'a>, { ids: IdRangeIter, document: &'a super::ExecutableDocument, @@ -114,7 +116,7 @@ where impl<'a, T> Iterator for IdIter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { type Item = (T::Id, ::Reader<'a>); @@ -132,21 +134,21 @@ where impl<'a, T> ExactSizeIterator for IdIter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { } impl<'a, T> FusedIterator for IdIter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { } impl<'a, T> DoubleEndedIterator for IdIter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { // Required method @@ -159,7 +161,7 @@ where impl<'a, T> fmt::Debug for IdIter<'a, T> where - T: IdReader + Copy, + T: IdReader<'a> + Copy, Self: Iterator, ::Item: fmt::Debug, { diff --git a/cynic-parser/src/printing/display/executable.rs b/cynic-parser/src/printing/display/executable.rs index f26fa651..43c8c2eb 100644 --- a/cynic-parser/src/printing/display/executable.rs +++ b/cynic-parser/src/printing/display/executable.rs @@ -68,7 +68,7 @@ impl fmt::Display for FragmentDefinition<'_> { } } -impl fmt::Display for iter::Iter<'_, VariableDefinition<'_>> { +impl<'a> fmt::Display for iter::Iter<'a, VariableDefinition<'a>> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.len() != 0 { write!(f, "(")?; @@ -96,7 +96,7 @@ impl std::fmt::Display for VariableDefinition<'_> { } } -impl std::fmt::Display for iter::Iter<'_, Selection<'_>> { +impl<'a> std::fmt::Display for iter::Iter<'a, Selection<'a>> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.len() != 0 { writeln!(f, "{{")?; @@ -166,7 +166,7 @@ impl fmt::Display for FragmentSpread<'_> { } } -impl fmt::Display for iter::Iter<'_, Directive<'_>> { +impl<'a> fmt::Display for iter::Iter<'a, Directive<'a>> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for directive in self.clone() { write!(f, " {directive}")?; @@ -181,7 +181,7 @@ impl fmt::Display for Directive<'_> { } } -impl fmt::Display for iter::Iter<'_, Argument<'_>> { +impl<'a> fmt::Display for iter::Iter<'a, Argument<'a>> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.len() != 0 { write!(f, "(")?; diff --git a/cynic-parser/src/printing/pretty/type_system/field_sequence.rs b/cynic-parser/src/printing/pretty/type_system/field_sequence.rs index 6c86676c..7f736f97 100644 --- a/cynic-parser/src/printing/pretty/type_system/field_sequence.rs +++ b/cynic-parser/src/printing/pretty/type_system/field_sequence.rs @@ -1,4 +1,4 @@ -use std::iter::Enumerate; +use std::{iter::Enumerate, marker::PhantomData}; use pretty::{DocAllocator, Pretty}; @@ -6,7 +6,7 @@ use crate::{common::IdOperations, printing::pretty::printer::PrettyOptions}; use super::{ iter::IdReader, Allocator, EnumValueDefinition, FieldDefinition, InputValueDefinition, - NodeDisplay, TypeSystemId, + NodeDisplay, }; /// A sequence of things with docstrings attached. @@ -20,17 +20,17 @@ use super::{ /// but arguments should use ArgumentSequence pub(super) struct FieldSequence<'a, T> where - T: IdReader + Field<'a>, + T: IdReader<'a> + Field<'a>, { - iterator: Enumerate::Id as TypeSystemId>::Reader<'a>>>, + iterator: Enumerate>, options: PrettyOptions, + phantom: PhantomData<&'a T>, } impl<'a, T> FieldSequence<'a, T> where - T: IdReader + Field<'a>, + T: IdReader<'a> + Field<'a>, T::Id: IdOperations, - <::Id as TypeSystemId>::Reader<'a>: Field<'a>, { pub fn new(iterator: crate::type_system::iter::Iter<'a, T>, options: PrettyOptions) -> Self { let mut fields = iterator.collect::>(); @@ -41,6 +41,7 @@ where FieldSequence { iterator: fields.into_iter().enumerate(), options, + phantom: PhantomData, } } } @@ -82,11 +83,9 @@ impl<'a> Field<'a> for EnumValueDefinition<'a> { impl<'a, T> Pretty<'a, Allocator<'a>> for FieldSequence<'a, T> where - T: Field<'a> + IdReader, + T: Field<'a> + IdReader<'a>, T::Id: IdOperations, - // This is a bit much :/ - <::Id as TypeSystemId>::Reader<'a>: Field<'a>, - NodeDisplay<<::Id as TypeSystemId>::Reader<'a>>: Pretty<'a, Allocator<'a>>, + NodeDisplay: Pretty<'a, Allocator<'a>>, { fn pretty(self, allocator: &'a Allocator<'a>) -> pretty::DocBuilder<'a, Allocator<'a>, ()> { let mut document = allocator.nil(); diff --git a/cynic-parser/src/type_system/definitions.rs b/cynic-parser/src/type_system/definitions.rs index 44399d54..5fb8464d 100644 --- a/cynic-parser/src/type_system/definitions.rs +++ b/cynic-parser/src/type_system/definitions.rs @@ -152,6 +152,10 @@ impl TypeSystemId for DefinitionId { } } -impl IdReader for Definition<'_> { +impl<'a> IdReader<'a> for Definition<'a> { type Id = DefinitionId; + + fn new(id: Self::Id, document: &'a super::TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/arguments.rs b/cynic-parser/src/type_system/generated/arguments.rs index 30a2c43b..9968f0f7 100644 --- a/cynic-parser/src/type_system/generated/arguments.rs +++ b/cynic-parser/src/type_system/generated/arguments.rs @@ -54,6 +54,9 @@ impl TypeSystemId for ArgumentId { } } -impl IdReader for Argument<'_> { +impl<'a> IdReader<'a> for Argument<'a> { type Id = ArgumentId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/descriptions.rs b/cynic-parser/src/type_system/generated/descriptions.rs index 320bf6b1..7e430a66 100644 --- a/cynic-parser/src/type_system/generated/descriptions.rs +++ b/cynic-parser/src/type_system/generated/descriptions.rs @@ -48,6 +48,9 @@ impl TypeSystemId for DescriptionId { } } -impl IdReader for Description<'_> { +impl<'a> IdReader<'a> for Description<'a> { type Id = DescriptionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/directives.rs b/cynic-parser/src/type_system/generated/directives.rs index 59d4b8f0..5213f98c 100644 --- a/cynic-parser/src/type_system/generated/directives.rs +++ b/cynic-parser/src/type_system/generated/directives.rs @@ -77,8 +77,11 @@ impl TypeSystemId for DirectiveDefinitionId { } } -impl IdReader for DirectiveDefinition<'_> { +impl<'a> IdReader<'a> for DirectiveDefinition<'a> { type Id = DirectiveDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } pub struct DirectiveRecord { @@ -122,6 +125,9 @@ impl TypeSystemId for DirectiveId { } } -impl IdReader for Directive<'_> { +impl<'a> IdReader<'a> for Directive<'a> { type Id = DirectiveId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/enums.rs b/cynic-parser/src/type_system/generated/enums.rs index d6e0e20c..cbff1cad 100644 --- a/cynic-parser/src/type_system/generated/enums.rs +++ b/cynic-parser/src/type_system/generated/enums.rs @@ -70,8 +70,11 @@ impl TypeSystemId for EnumDefinitionId { } } -impl IdReader for EnumDefinition<'_> { +impl<'a> IdReader<'a> for EnumDefinition<'a> { type Id = EnumDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } pub struct EnumValueDefinitionRecord { @@ -130,6 +133,9 @@ impl TypeSystemId for EnumValueDefinitionId { } } -impl IdReader for EnumValueDefinition<'_> { +impl<'a> IdReader<'a> for EnumValueDefinition<'a> { type Id = EnumValueDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/fields.rs b/cynic-parser/src/type_system/generated/fields.rs index 0894f8d8..e533bf03 100644 --- a/cynic-parser/src/type_system/generated/fields.rs +++ b/cynic-parser/src/type_system/generated/fields.rs @@ -78,6 +78,9 @@ impl TypeSystemId for FieldDefinitionId { } } -impl IdReader for FieldDefinition<'_> { +impl<'a> IdReader<'a> for FieldDefinition<'a> { type Id = FieldDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/input_objects.rs b/cynic-parser/src/type_system/generated/input_objects.rs index fbafb69e..c1f46593 100644 --- a/cynic-parser/src/type_system/generated/input_objects.rs +++ b/cynic-parser/src/type_system/generated/input_objects.rs @@ -71,6 +71,9 @@ impl TypeSystemId for InputObjectDefinitionId { } } -impl IdReader for InputObjectDefinition<'_> { +impl<'a> IdReader<'a> for InputObjectDefinition<'a> { type Id = InputObjectDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/input_values.rs b/cynic-parser/src/type_system/generated/input_values.rs index 8df7843f..12e4e5d4 100644 --- a/cynic-parser/src/type_system/generated/input_values.rs +++ b/cynic-parser/src/type_system/generated/input_values.rs @@ -87,6 +87,9 @@ impl TypeSystemId for InputValueDefinitionId { } } -impl IdReader for InputValueDefinition<'_> { +impl<'a> IdReader<'a> for InputValueDefinition<'a> { type Id = InputValueDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/interfaces.rs b/cynic-parser/src/type_system/generated/interfaces.rs index d870dde0..f22407b3 100644 --- a/cynic-parser/src/type_system/generated/interfaces.rs +++ b/cynic-parser/src/type_system/generated/interfaces.rs @@ -84,6 +84,9 @@ impl TypeSystemId for InterfaceDefinitionId { } } -impl IdReader for InterfaceDefinition<'_> { +impl<'a> IdReader<'a> for InterfaceDefinition<'a> { type Id = InterfaceDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/name.rs b/cynic-parser/src/type_system/generated/name.rs new file mode 100644 index 00000000..517f27f0 --- /dev/null +++ b/cynic-parser/src/type_system/generated/name.rs @@ -0,0 +1,49 @@ +use super::prelude::*; +use super::{ids::NameId, TypeSystemId}; +#[allow(unused_imports)] +use std::fmt::{self, Write}; + +pub struct NameRecord { + pub text: StringId, + pub span: Span, +} + +#[derive(Clone, Copy)] +pub struct Name<'a>(pub(in super::super) ReadContext<'a, NameId>); + +impl<'a> Name<'a> { + pub fn text(&self) -> &'a str { + let document = &self.0.document; + document.lookup(document.lookup(self.0.id).text) + } + pub fn span(&self) -> Span { + let document = self.0.document; + document.lookup(self.0.id).span + } +} + +impl Name<'_> { + pub fn id(&self) -> NameId { + self.0.id + } +} + +impl fmt::Debug for Name<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Name") + .field("text", &self.text()) + .field("span", &self.span()) + .finish() + } +} + +impl TypeSystemId for NameId { + type Reader<'a> = Name<'a>; + fn read(self, document: &TypeSystemDocument) -> Self::Reader<'_> { + Name(ReadContext { id: self, document }) + } +} + +impl IdReader for Name<'_> { + type Id = NameId; +} \ No newline at end of file diff --git a/cynic-parser/src/type_system/generated/objects.rs b/cynic-parser/src/type_system/generated/objects.rs index 777b68c8..c6192f96 100644 --- a/cynic-parser/src/type_system/generated/objects.rs +++ b/cynic-parser/src/type_system/generated/objects.rs @@ -84,6 +84,9 @@ impl TypeSystemId for ObjectDefinitionId { } } -impl IdReader for ObjectDefinition<'_> { +impl<'a> IdReader<'a> for ObjectDefinition<'a> { type Id = ObjectDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/scalars.rs b/cynic-parser/src/type_system/generated/scalars.rs index 6405ba80..305a38e5 100644 --- a/cynic-parser/src/type_system/generated/scalars.rs +++ b/cynic-parser/src/type_system/generated/scalars.rs @@ -64,6 +64,9 @@ impl TypeSystemId for ScalarDefinitionId { } } -impl IdReader for ScalarDefinition<'_> { +impl<'a> IdReader<'a> for ScalarDefinition<'a> { type Id = ScalarDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/schemas.rs b/cynic-parser/src/type_system/generated/schemas.rs index 873d3b77..79abdd61 100644 --- a/cynic-parser/src/type_system/generated/schemas.rs +++ b/cynic-parser/src/type_system/generated/schemas.rs @@ -64,8 +64,11 @@ impl TypeSystemId for SchemaDefinitionId { } } -impl IdReader for SchemaDefinition<'_> { +impl<'a> IdReader<'a> for SchemaDefinition<'a> { type Id = SchemaDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } pub struct RootOperationTypeDefinitionRecord { @@ -117,6 +120,9 @@ impl TypeSystemId for RootOperationTypeDefinitionId { } } -impl IdReader for RootOperationTypeDefinition<'_> { +impl<'a> IdReader<'a> for RootOperationTypeDefinition<'a> { type Id = RootOperationTypeDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/generated/unions.rs b/cynic-parser/src/type_system/generated/unions.rs index 507b54a4..273093ae 100644 --- a/cynic-parser/src/type_system/generated/unions.rs +++ b/cynic-parser/src/type_system/generated/unions.rs @@ -70,8 +70,11 @@ impl TypeSystemId for UnionDefinitionId { } } -impl IdReader for UnionDefinition<'_> { +impl<'a> IdReader<'a> for UnionDefinition<'a> { type Id = UnionDefinitionId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } pub struct UnionMemberRecord { @@ -115,6 +118,9 @@ impl TypeSystemId for UnionMemberId { } } -impl IdReader for UnionMember<'_> { +impl<'a> IdReader<'a> for UnionMember<'a> { type Id = UnionMemberId; + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self { + document.read(id) + } } diff --git a/cynic-parser/src/type_system/iter.rs b/cynic-parser/src/type_system/iter.rs index 4991fde0..e57be06f 100644 --- a/cynic-parser/src/type_system/iter.rs +++ b/cynic-parser/src/type_system/iter.rs @@ -2,7 +2,7 @@ use std::{fmt, iter::FusedIterator}; use crate::common::{IdOperations, IdRange, IdRangeIter}; -use super::TypeSystemId; +use super::{TypeSystemDocument, TypeSystemId}; /// Iterator for readers in the executable module /// @@ -10,7 +10,7 @@ use super::TypeSystemId; #[derive(Clone)] pub struct Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, { ids: IdRangeIter, document: &'a super::TypeSystemDocument, @@ -18,7 +18,7 @@ where impl<'a, T> Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, { pub(crate) fn new(range: IdRange, document: &'a super::TypeSystemDocument) -> Self where @@ -35,19 +35,21 @@ where } } -pub trait IdReader { +pub trait IdReader<'a> { type Id: TypeSystemId; + + fn new(id: Self::Id, document: &'a TypeSystemDocument) -> Self; } impl<'a, T> Iterator for Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { - type Item = ::Reader<'a>; + type Item = T; fn next(&mut self) -> Option { - Some(self.document.read(self.ids.next()?)) + Some(T::new(self.ids.next()?, self.document)) } fn size_hint(&self) -> (usize, Option) { @@ -57,32 +59,32 @@ where impl<'a, T> ExactSizeIterator for Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { } impl<'a, T> FusedIterator for Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { } impl<'a, T> DoubleEndedIterator for Iter<'a, T> where - T: IdReader, + T: IdReader<'a>, T::Id: IdOperations, { // Required method fn next_back(&mut self) -> Option { - Some(self.document.read(self.ids.next_back()?)) + Some(T::new(self.ids.next_back()?, self.document)) } } impl<'a, T> fmt::Debug for Iter<'a, T> where - T: IdReader + Copy, + T: IdReader<'a> + Copy, Self: Iterator, ::Item: fmt::Debug, {