From 965ac6ae90e3a2113e6386b227f076c04229e9a1 Mon Sep 17 00:00:00 2001 From: sunli829 Date: Sat, 14 May 2022 16:43:28 +0800 Subject: [PATCH] Fixed `OneofObject` restriction on inner types being unique. #923 --- CHANGELOG.md | 1 + derive/src/oneof_object.rs | 12 +----------- derive/src/union.rs | 8 +++++--- examples | 2 +- tests/oneof_object.rs | 30 ++++++++++++++++++++++++++++++ 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9099a378..3854afeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump [`uuid`](https://crates.io/crates/uuid) to `1.0.0`. [#907](https://github.com/async-graphql/async-graphql/pull/907/files) - Add some options for exporting SDL. [#877](https://github.com/async-graphql/async-graphql/issues/877) - Cache parsed `ExecuteDocument` in APQ. [#919](https://github.com/async-graphql/async-graphql/issues/919) +- Fixed `OneofObject` restriction on inner types being unique. [#923](https://github.com/async-graphql/async-graphql/issues/923) # [3.0.38] 2022-4-8 diff --git a/derive/src/oneof_object.rs b/derive/src/oneof_object.rs index 12a70ac9..3b13021e 100644 --- a/derive/src/oneof_object.rs +++ b/derive/src/oneof_object.rs @@ -1,5 +1,3 @@ -use std::collections::HashSet; - use darling::ast::{Data, Style}; use proc_macro::TokenStream; use quote::quote; @@ -31,7 +29,6 @@ pub fn generate(object_args: &args::OneofObject) -> GeneratorResult } }; - let mut enum_items = HashSet::new(); let mut enum_names = Vec::new(); let mut schema_fields = Vec::new(); let mut parse_item = Vec::new(); @@ -70,14 +67,7 @@ pub fn generate(object_args: &args::OneofObject) -> GeneratorResult } }; - if let Type::Path(p) = ty { - // This validates that the field type wasn't already used - if !enum_items.insert(p) { - return Err( - Error::new_spanned(ty, "This type already used in another variant").into(), - ); - } - + if let Type::Path(_) = ty { enum_names.push(enum_name); let secret = variant.secret; diff --git a/derive/src/union.rs b/derive/src/union.rs index 49df7ff5..dceb5a07 100644 --- a/derive/src/union.rs +++ b/derive/src/union.rs @@ -70,9 +70,11 @@ pub fn generate(union_args: &args::Union) -> GeneratorResult { if matches!(ty, Type::Path(_) | Type::Macro(_)) { // This validates that the field type wasn't already used if !enum_items.insert(ty) { - return Err( - Error::new_spanned(&ty, "This type already used in another variant").into(), - ); + return Err(Error::new_spanned( + &ty, + "This type is already used in another variant", + ) + .into()); } enum_names.push(enum_name); diff --git a/examples b/examples index d359d0ea..fa8fc5dd 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit d359d0ea3116326daf753f08233219530b8ec10b +Subproject commit fa8fc5dde0e1f70dee67719eceecfc9ade250d1f diff --git a/tests/oneof_object.rs b/tests/oneof_object.rs index 297237aa..37177a35 100644 --- a/tests/oneof_object.rs +++ b/tests/oneof_object.rs @@ -313,3 +313,33 @@ async fn test_oneof_object_vec() { }) ); } + +#[tokio::test] +async fn test_issue_923() { + #[derive(OneofObject)] + enum Filter { + Any(Vec), + All(Vec), + } + + pub struct Query; + + #[Object] + impl Query { + async fn query(&self, filter: Filter) -> bool { + match filter { + Filter::Any(values) => assert_eq!(values, vec!["a".to_string(), "b".to_string()]), + Filter::All(values) => assert_eq!(values, vec!["c".to_string(), "d".to_string()]), + } + true + } + } + + let schema = Schema::new(Query, EmptyMutation, EmptySubscription); + + let query = r#"{ query(filter: {any: ["a", "b"]}) }"#; + schema.execute(query).await.into_result().unwrap(); + + let query = r#"{ query(filter: {all: ["c", "d"]}) }"#; + schema.execute(query).await.into_result().unwrap(); +}