Fix the problem that the fields of the list are not merged correctly.#345

This commit is contained in:
Sunli 2020-11-27 10:26:23 +08:00
parent 3e82e1737c
commit 1e21e29fd9
2 changed files with 63 additions and 9 deletions

View File

@ -77,6 +77,32 @@ pub async fn resolve_container_serial<'a, T: ContainerType + Send + Sync>(
resolve_container_inner(ctx, root, false).await
}
fn insert_value(target: &mut BTreeMap<Name, Value>, name: Name, value: Value) {
if let Some(prev_value) = target.get_mut(&name) {
if let Value::Object(target_map) = prev_value {
if let Value::Object(obj) = value {
for (key, value) in obj.into_iter() {
insert_value(target_map, key, value);
}
}
} else if let Value::List(target_list) = prev_value {
if let Value::List(list) = value {
for (idx, value) in list.into_iter().enumerate() {
if let Some(Value::Object(target_map)) = target_list.get_mut(idx) {
if let Value::Object(obj) = value {
for (key, value) in obj.into_iter() {
insert_value(target_map, key, value);
}
}
}
}
}
}
} else {
target.insert(name, value);
}
}
async fn resolve_container_inner<'a, T: ContainerType + Send + Sync>(
ctx: &ContextSelectionSet<'a>,
root: &'a T,
@ -97,15 +123,7 @@ async fn resolve_container_inner<'a, T: ContainerType + Send + Sync>(
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);
}
insert_value(&mut map, name, value);
}
Ok(Value::Object(map))
}

View File

@ -82,3 +82,39 @@ pub async fn test_field_object_merge() {
})
);
}
#[async_std::test]
pub async fn test_field_object_merge2() {
#[derive(SimpleObject)]
struct MyObject {
a: i32,
b: i32,
c: i32,
}
struct Query;
#[Object]
impl Query {
async fn obj(&self) -> Vec<MyObject> {
vec![MyObject { a: 1, b: 2, c: 3 }, MyObject { a: 4, b: 5, c: 6 }]
}
}
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
let query = r#"
{
obj { a }
obj { b }
}
"#;
assert_eq!(
schema.execute(query).await.data,
value!({
"obj": [
{ "a": 1, "b": 2 },
{ "a": 4, "b": 5 },
]
})
);
}