async_graphql/resolver_utils/
list.rs1use crate::{
2 extensions::ResolveInfo, parser::types::Field, ContextSelectionSet, OutputType, Positioned,
3 ServerResult, Value,
4};
5
6pub async fn resolve_list<'a, T: OutputType + 'a>(
8 ctx: &ContextSelectionSet<'a>,
9 field: &Positioned<Field>,
10 iter: impl IntoIterator<Item = T>,
11 len: Option<usize>,
12) -> ServerResult<Value> {
13 let extensions = &ctx.query_env.extensions;
14 if !extensions.is_empty() {
15 let mut futures = len.map(Vec::with_capacity).unwrap_or_default();
16 for (idx, item) in iter.into_iter().enumerate() {
17 futures.push({
18 let ctx = ctx.clone();
19 async move {
20 let ctx_idx = ctx.with_index(idx);
21 let extensions = &ctx.query_env.extensions;
22
23 let resolve_info = ResolveInfo {
24 path_node: ctx_idx.path_node.as_ref().unwrap(),
25 parent_type: &Vec::<T>::type_name(),
26 return_type: &T::qualified_type_name(),
27 name: field.node.name.node.as_str(),
28 alias: field.node.alias.as_ref().map(|alias| alias.node.as_str()),
29 is_for_introspection: ctx_idx.is_for_introspection,
30 field: &field.node,
31 };
32 let resolve_fut = async {
33 OutputType::resolve(&item, &ctx_idx, field)
34 .await
35 .map(Option::Some)
36 .map_err(|err| ctx_idx.set_error_path(err))
37 };
38 futures_util::pin_mut!(resolve_fut);
39 extensions
40 .resolve(resolve_info, &mut resolve_fut)
41 .await
42 .map(|value| value.expect("You definitely encountered a bug!"))
43 }
44 });
45 }
46 Ok(Value::List(
47 futures_util::future::try_join_all(futures).await?,
48 ))
49 } else {
50 let mut futures = len.map(Vec::with_capacity).unwrap_or_default();
51 for (idx, item) in iter.into_iter().enumerate() {
52 let ctx_idx = ctx.with_index(idx);
53 futures.push(async move {
54 OutputType::resolve(&item, &ctx_idx, field)
55 .await
56 .map_err(|err| ctx_idx.set_error_path(err))
57 });
58 }
59 Ok(Value::List(
60 futures_util::future::try_join_all(futures).await?,
61 ))
62 }
63}