async-graphql/src/resolver_utils/list.rs

63 lines
2.5 KiB
Rust
Raw Normal View History

2022-04-19 04:25:11 +00:00
use crate::{
extensions::ResolveInfo, parser::types::Field, ContextSelectionSet, OutputType, Positioned,
ServerResult, Value,
};
2020-09-25 04:58:45 +00:00
/// Resolve an list by executing each of the items concurrently.
pub async fn resolve_list<'a, T: OutputType + 'a>(
2020-09-25 04:58:45 +00:00
ctx: &ContextSelectionSet<'a>,
field: &Positioned<Field>,
iter: impl IntoIterator<Item = T>,
2020-10-12 06:49:32 +00:00
len: Option<usize>,
2021-06-07 12:51:20 +00:00
) -> ServerResult<Value> {
2021-04-04 04:05:54 +00:00
let extensions = &ctx.query_env.extensions;
2021-04-04 06:43:23 +00:00
if !extensions.is_empty() {
2021-04-04 04:05:54 +00:00
let mut futures = len.map(Vec::with_capacity).unwrap_or_default();
for (idx, item) in iter.into_iter().enumerate() {
futures.push({
let ctx = ctx.clone();
async move {
let ctx_idx = ctx.with_index(idx);
2021-04-04 06:43:23 +00:00
let extensions = &ctx.query_env.extensions;
2021-04-04 04:05:54 +00:00
let resolve_info = ResolveInfo {
path_node: ctx_idx.path_node.as_ref().unwrap(),
parent_type: &Vec::<T>::type_name(),
return_type: &T::qualified_type_name(),
name: field.node.name.node.as_str(),
alias: field.node.alias.as_ref().map(|alias| alias.node.as_str()),
is_for_introspection: ctx_idx.is_for_introspection,
2021-04-04 04:05:54 +00:00
};
2021-06-07 12:51:20 +00:00
let resolve_fut = async {
OutputType::resolve(&item, &ctx_idx, field)
.await
.map(Option::Some)
.map_err(|err| ctx_idx.set_error_path(err))
};
2021-04-04 04:05:54 +00:00
futures_util::pin_mut!(resolve_fut);
extensions
.resolve(resolve_info, &mut resolve_fut)
.await
2021-06-07 12:51:20 +00:00
.map(|value| value.expect("You definitely encountered a bug!"))
2021-04-04 04:05:54 +00:00
}
});
}
2021-06-07 12:51:20 +00:00
Ok(Value::List(
futures_util::future::try_join_all(futures).await?,
))
2021-04-04 04:05:54 +00:00
} else {
let mut futures = len.map(Vec::with_capacity).unwrap_or_default();
for (idx, item) in iter.into_iter().enumerate() {
let ctx_idx = ctx.with_index(idx);
2021-06-07 12:51:20 +00:00
futures.push(async move {
OutputType::resolve(&item, &ctx_idx, field)
.await
.map_err(|err| ctx_idx.set_error_path(err))
});
2021-04-04 04:05:54 +00:00
}
2021-06-07 12:51:20 +00:00
Ok(Value::List(
futures_util::future::try_join_all(futures).await?,
))
2020-09-25 04:58:45 +00:00
}
}