diff --git a/async-graphql-derive/src/interface.rs b/async-graphql-derive/src/interface.rs index 9f66960a..3ca5065f 100644 --- a/async-graphql-derive/src/interface.rs +++ b/async-graphql-derive/src/interface.rs @@ -175,6 +175,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result }; methods.push(quote! { + #[inline] async fn #method_name #ctx_lifetime(&self, #(#decl_params),*) -> #ty { match self { #(#calls,)* diff --git a/src/types/connection/connection_type.rs b/src/types/connection/connection_type.rs index 52759b00..2cc26398 100644 --- a/src/types/connection/connection_type.rs +++ b/src/types/connection/connection_type.rs @@ -57,6 +57,35 @@ impl Connection { .collect(), } } + + #[doc(hidden)] + #[inline] + pub async fn page_info(&self) -> &PageInfo { + &self.page_info + } + + #[doc(hidden)] + #[inline] + pub async fn edges(&self) -> Option>>> { + Some( + self.nodes + .iter() + .map(|(cursor, extra_type, node)| { + Some(Edge { + cursor, + extra_type, + node, + }) + }) + .collect_vec(), + ) + } + + #[doc(hidden)] + #[inline] + pub async fn total_count(&self) -> Option { + self.total_count.map(|n| n as i32) + } } impl Type for Connection { @@ -145,25 +174,15 @@ impl ObjectType async fn resolve_field(&self, ctx: &Context<'_>, field: &Field) -> Result { if field.name.as_str() == "pageInfo" { let ctx_obj = ctx.with_selection_set(&field.selection_set); - let page_info = &self.page_info; - return OutputValueType::resolve(page_info, &ctx_obj, field.position).await; + return OutputValueType::resolve(self.page_info().await, &ctx_obj, field.position) + .await; } else if field.name.as_str() == "edges" { let ctx_obj = ctx.with_selection_set(&field.selection_set); - let edges = self - .nodes - .iter() - .map(|(cursor, extra_type, node)| Edge { - cursor, - extra_type, - node, - }) - .collect_vec(); - return OutputValueType::resolve(&edges, &ctx_obj, field.position).await; + return OutputValueType::resolve(&self.edges().await, &ctx_obj, field.position).await; } else if field.name.as_str() == "totalCount" { - return Ok(self - .total_count - .map(|n| (n as i32).into()) - .unwrap_or_else(|| serde_json::Value::Null)); + let ctx_obj = ctx.with_selection_set(&field.selection_set); + return OutputValueType::resolve(&self.total_count().await, &ctx_obj, field.position) + .await; } else if field.name.as_str() == T::type_name().to_plural().to_camel_case() { let ctx_obj = ctx.with_selection_set(&field.selection_set); let items = self.nodes.iter().map(|(_, _, item)| item).collect_vec(); diff --git a/src/types/connection/edge.rs b/src/types/connection/edge.rs index 31a10ca2..1738e3e3 100644 --- a/src/types/connection/edge.rs +++ b/src/types/connection/edge.rs @@ -12,6 +12,24 @@ pub struct Edge<'a, T, E> { pub extra_type: &'a E, } +impl<'a, T, E> Edge<'a, T, E> +where + T: OutputValueType + Send + Sync + 'a, + E: ObjectType + Sync + Send + 'a, +{ + #[doc(hidden)] + #[inline] + pub async fn node(&self) -> &T { + self.node + } + + #[doc(hidden)] + #[inline] + pub async fn cursor(&self) -> &str { + self.cursor + } +} + impl<'a, T, E> Type for Edge<'a, T, E> where T: OutputValueType + Send + Sync + 'a, @@ -89,9 +107,9 @@ where async fn resolve_field(&self, ctx: &Context<'_>, field: &Field) -> Result { if field.name.as_str() == "node" { let ctx_obj = ctx.with_selection_set(&field.selection_set); - return OutputValueType::resolve(self.node, &ctx_obj, field.position).await; + return OutputValueType::resolve(self.node().await, &ctx_obj, field.position).await; } else if field.name.as_str() == "cursor" { - return Ok(self.cursor.into()); + return Ok(self.cursor().await.into()); } self.extra_type.resolve_field(ctx, field).await