From 6f47b11fed97363d6103cca5a7169d719f8e9ab9 Mon Sep 17 00:00:00 2001 From: Koxiaet <38139193+Koxiaet@users.noreply.github.com> Date: Fri, 16 Oct 2020 07:12:21 +0100 Subject: [PATCH] Reduce code duplication in container resolver --- src/resolver_utils/container.rs | 44 +++++++++++++++------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/resolver_utils/container.rs b/src/resolver_utils/container.rs index aceecc0d..d74742dd 100644 --- a/src/resolver_utils/container.rs +++ b/src/resolver_utils/container.rs @@ -57,46 +57,42 @@ impl ContainerType for &T { } } -// TODO: reduce code duplication between the two below functions? - /// Resolve an container by executing each of the fields concurrently. pub async fn resolve_container<'a, T: ContainerType + Send + Sync>( ctx: &ContextSelectionSet<'a>, root: &'a T, ) -> ServerResult { - let mut fields = Fields(Vec::new()); - 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_container_inner(ctx, root, true).await } /// Resolve an container by executing each of the fields serially. pub async fn resolve_container_serial<'a, T: ContainerType + Send + Sync>( ctx: &ContextSelectionSet<'a>, root: &'a T, +) -> ServerResult { + 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 { let mut fields = Fields(Vec::new()); 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(); - for field in futures { - let (name, value) = field.await?; - + for (name, value) in res { if let Value::Object(b) = value { if let Some(Value::Object(a)) = map.get_mut(&name) { a.extend(b);