async_graphql/resolver_utils/
list.rs

1use crate::{
2    extensions::ResolveInfo, parser::types::Field, ContextSelectionSet, OutputType, Positioned,
3    ServerResult, Value,
4};
5
6/// Resolve an list by executing each of the items concurrently.
7pub 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}