use crate::extensions::{ErrorLogger, Extension, ExtensionContext, ResolveInfo}; use crate::parser::types::Field; use crate::{ContextSelectionSet, OutputValueType, PathSegment, Positioned, ServerResult, Type}; /// Resolve an list by executing each of the items concurrently. pub async fn resolve_list<'a, T: OutputValueType + Send + Sync + 'a>( ctx: &ContextSelectionSet<'a>, field: &Positioned, iter: impl IntoIterator, ) -> ServerResult { let mut futures = Vec::new(); for (idx, item) in iter.into_iter().enumerate() { let ctx_idx = ctx.with_index(idx); futures.push(async move { let resolve_info = ResolveInfo { resolve_id: ctx_idx.resolve_id, path_node: ctx_idx.path_node.as_ref().unwrap(), parent_type: &Vec::::type_name(), return_type: &T::qualified_type_name(), }; let ctx_extension = ExtensionContext { schema_data: &ctx.schema_env.data, query_data: &ctx.query_env.ctx_data, }; ctx_idx .query_env .extensions .lock() .resolve_start(&ctx_extension, &resolve_info); let res = OutputValueType::resolve(&item, &ctx_idx, field) .await .map_err(|e| e.path(PathSegment::Index(idx))) .log_error(&ctx_extension, &ctx_idx.query_env.extensions)?; ctx_idx .query_env .extensions .lock() .resolve_end(&ctx_extension, &resolve_info); ServerResult::Ok(res) }); } Ok(futures::future::try_join_all(futures).await?.into()) }