From 63d8a3d1a03a28b8b5665907e7c25993db3f48f2 Mon Sep 17 00:00:00 2001 From: Carlos Diaz-Padron Date: Sun, 18 Feb 2018 16:45:31 -0800 Subject: [PATCH] Handle list merging --- juniper/src/executor_tests/executor.rs | 60 ++++++++++++++++++++++---- juniper/src/types/base.rs | 26 +++++++++-- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/juniper/src/executor_tests/executor.rs b/juniper/src/executor_tests/executor.rs index 00339f8e..a130fec6 100644 --- a/juniper/src/executor_tests/executor.rs +++ b/juniper/src/executor_tests/executor.rs @@ -203,12 +203,22 @@ mod merge_parallel_inline_fragments { use types::scalars::EmptyMutation; struct Type; + struct Other; graphql_object!(Type: () |&self| { field a() -> &str { "Apple" } field b() -> &str { "Banana" } field c() -> &str { "Cherry" } field deep() -> Type { Type } + field other() -> Vec { vec![Other, Other] } + }); + + graphql_object!(Other: () |&self| { + field a() -> &str { "Apple" } + field b() -> &str { "Banana" } + field c() -> &str { "Cherry" } + field deep() -> Type { Type } + field other() -> Vec { vec![Other, Other] } }); #[test] @@ -218,15 +228,24 @@ mod merge_parallel_inline_fragments { { a, ...FragOne } fragment FragOne on Type { b - deep { + deep: deep { b - deeper: deep { b } + deeper: other { + deepest: deep { + b + } + } ... on Type { c - deeper: deep { c } + deeper: other { + deepest: deep { + c + } + } } } + c }"; @@ -251,12 +270,37 @@ mod merge_parallel_inline_fragments { ("b", Value::string("Banana")), ( "deeper", - Value::object( + Value::list( vec![ - ("b", Value::string("Banana")), - ("c", Value::string("Cherry")), - ].into_iter() - .collect(), + Value::object( + vec![ + ( + "deepest", + Value::object( + vec![ + ("b", Value::string("Banana")), + ("c", Value::string("Cherry")), + ].into_iter() + .collect(), + ), + ), + ].into_iter().collect() + ), + Value::object( + vec![ + ( + "deepest", + Value::object( + vec![ + ("b", Value::string("Banana")), + ("c", Value::string("Cherry")), + ].into_iter() + .collect(), + ), + ), + ].into_iter().collect() + ), + ] ), ), ("c", Value::string("Cherry")), diff --git a/juniper/src/types/base.rs b/juniper/src/types/base.rs index 90370d21..1df6d77c 100644 --- a/juniper/src/types/base.rs +++ b/juniper/src/types/base.rs @@ -505,11 +505,29 @@ fn is_excluded(directives: &Option>>, vars: &Variables) fn merge_key_into(result: &mut OrderMap, response_name: &str, value: Value) { match result.entry(response_name.to_owned()) { - Entry::Occupied(mut e) => match (e.get_mut().as_mut_object_value(), value) { - (Some(dest_obj), Value::Object(src_obj)) => { - merge_maps(dest_obj, src_obj); + Entry::Occupied(mut e) => { + match e.get_mut() { + &mut Value::Object(ref mut dest_obj) => { + if let Value::Object(src_obj) = value { + merge_maps(dest_obj, src_obj); + } + }, + &mut Value::List(ref mut dest_list) => { + if let Value::List(src_list) = value { + dest_list.iter_mut().zip(src_list.into_iter()).for_each(|(d, s)| { + match d { + &mut Value::Object(ref mut d_obj) => { + if let Value::Object(s_obj) = s { + merge_maps(d_obj, s_obj); + } + }, + _ => {}, + } + }); + } + }, + _ => {} } - _ => {} }, Entry::Vacant(e) => { e.insert(value);