Reduce code duplication in container resolver
This commit is contained in:
parent
ec8ec740be
commit
6f47b11fed
|
@ -57,46 +57,42 @@ impl<T: ContainerType + Send + Sync> ContainerType for &T {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: reduce code duplication between the two below functions?
|
|
||||||
|
|
||||||
/// Resolve an container by executing each of the fields concurrently.
|
/// Resolve an container by executing each of the fields concurrently.
|
||||||
pub async fn resolve_container<'a, T: ContainerType + Send + Sync>(
|
pub async fn resolve_container<'a, T: ContainerType + Send + Sync>(
|
||||||
ctx: &ContextSelectionSet<'a>,
|
ctx: &ContextSelectionSet<'a>,
|
||||||
root: &'a T,
|
root: &'a T,
|
||||||
) -> ServerResult<Value> {
|
) -> ServerResult<Value> {
|
||||||
let mut fields = Fields(Vec::new());
|
resolve_container_inner(ctx, root, true).await
|
||||||
fields.add_set(ctx, root)?;
|
|
||||||
let futures = fields.0;
|
|
||||||
|
|
||||||
let res = futures::future::try_join_all(futures).await?;
|
|
||||||
let mut map = BTreeMap::new();
|
|
||||||
for (name, value) in res {
|
|
||||||
if let Value::Object(b) = value {
|
|
||||||
if let Some(Value::Object(a)) = map.get_mut(&name) {
|
|
||||||
a.extend(b);
|
|
||||||
} else {
|
|
||||||
map.insert(name, Value::Object(b));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
map.insert(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(Value::Object(map))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve an container by executing each of the fields serially.
|
/// Resolve an container by executing each of the fields serially.
|
||||||
pub async fn resolve_container_serial<'a, T: ContainerType + Send + Sync>(
|
pub async fn resolve_container_serial<'a, T: ContainerType + Send + Sync>(
|
||||||
ctx: &ContextSelectionSet<'a>,
|
ctx: &ContextSelectionSet<'a>,
|
||||||
root: &'a T,
|
root: &'a T,
|
||||||
|
) -> ServerResult<Value> {
|
||||||
|
resolve_container_inner(ctx, root, false).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn resolve_container_inner<'a, T: ContainerType + Send + Sync>(
|
||||||
|
ctx: &ContextSelectionSet<'a>,
|
||||||
|
root: &'a T,
|
||||||
|
parallel: bool,
|
||||||
) -> ServerResult<Value> {
|
) -> ServerResult<Value> {
|
||||||
let mut fields = Fields(Vec::new());
|
let mut fields = Fields(Vec::new());
|
||||||
fields.add_set(ctx, root)?;
|
fields.add_set(ctx, root)?;
|
||||||
let futures = fields.0;
|
|
||||||
|
let res = if parallel {
|
||||||
|
futures::future::try_join_all(fields.0).await?
|
||||||
|
} else {
|
||||||
|
let mut results = Vec::with_capacity(fields.0.len());
|
||||||
|
for field in fields.0 {
|
||||||
|
results.push(field.await?);
|
||||||
|
}
|
||||||
|
results
|
||||||
|
};
|
||||||
|
|
||||||
let mut map = BTreeMap::new();
|
let mut map = BTreeMap::new();
|
||||||
for field in futures {
|
for (name, value) in res {
|
||||||
let (name, value) = field.await?;
|
|
||||||
|
|
||||||
if let Value::Object(b) = value {
|
if let Value::Object(b) = value {
|
||||||
if let Some(Value::Object(a)) = map.get_mut(&name) {
|
if let Some(Value::Object(a)) = map.get_mut(&name) {
|
||||||
a.extend(b);
|
a.extend(b);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user