From f7a2fe5fa5670b1cb92790b3de177e3e0b478a17 Mon Sep 17 00:00:00 2001 From: sunli Date: Tue, 21 Apr 2020 20:47:48 +0800 Subject: [PATCH] Add SchemaBuilder::register_type method --- async-graphql-derive/src/args.rs | 12 ---------- async-graphql-derive/src/interface.rs | 34 +++------------------------ src/model/type.rs | 6 ----- src/registry.rs | 1 - src/schema.rs | 6 +++++ tests/interface.rs | 6 +++-- 6 files changed, 13 insertions(+), 52 deletions(-) diff --git a/async-graphql-derive/src/args.rs b/async-graphql-derive/src/args.rs index 37ee6a1e..f80bb59f 100644 --- a/async-graphql-derive/src/args.rs +++ b/async-graphql-derive/src/args.rs @@ -783,7 +783,6 @@ pub struct Interface { pub internal: bool, pub name: Option, pub desc: Option, - pub implements: Option, pub fields: Vec, pub extends: bool, } @@ -793,7 +792,6 @@ impl Interface { let mut internal = false; let mut name = None; let mut desc = None; - let mut implements = None; let mut fields = Vec::new(); let mut extends = false; @@ -824,15 +822,6 @@ impl Interface { "Attribute 'desc' should be a string.", )); } - } else if nv.path.is_ident("implements") { - if let syn::Lit::Str(lit) = nv.lit { - implements = Some(lit.value()); - } else { - return Err(Error::new_spanned( - &nv.lit, - "Implements 'desc' should be a string.", - )); - } } } NestedMeta::Meta(Meta::List(ls)) if ls.path.is_ident("field") => { @@ -846,7 +835,6 @@ impl Interface { internal, name, desc, - implements, fields, extends, }) diff --git a/async-graphql-derive/src/interface.rs b/async-graphql-derive/src/interface.rs index 1ca486c7..7a3e1eda 100644 --- a/async-graphql-derive/src/interface.rs +++ b/async-graphql-derive/src/interface.rs @@ -23,10 +23,6 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result Fields::Unit => None, _ => return Err(Error::new_spanned(input, "All fields must be unnamed.")), }; - let implements = match &interface_args.implements { - Some(implements) => quote! { Some(#implements) }, - None => quote! { None }, - }; let extends = interface_args.extends; let mut enum_names = Vec::new(); let mut enum_items = Vec::new(); @@ -46,13 +42,6 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result let mut collect_inline_fields = Vec::new(); let mut get_introspection_typename = Vec::new(); - if let Some(implements) = &interface_args.implements { - let implements_ident = Ident::new(implements, Span::call_site()); - registry_types.push(quote! { - <#implements_ident as #crate_name::Type>::create_type_info(registry); - }); - } - if let Some(fields) = fields { for field in fields { if let Type::Path(p) = &field.ty { @@ -76,29 +65,13 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result possible_types.insert(<#p as #crate_name::Type>::type_name().to_string()); }); - let collect_self_fields = Some(quote! { - else if name == <#ident as #crate_name::Type>::type_name() { - return #crate_name::collect_fields(ctx, obj, futures); - } - }); - let collect_parent_interface_fields = - if let Some(implements) = &interface_args.implements { - let implements_ident = Ident::new(implements, Span::call_site()); - Some(quote! { - else if name == <#implements_ident as #crate_name::Type>::type_name() { - return #crate_name::collect_fields(ctx, obj, futures); - } - }) - } else { - None - }; - collect_inline_fields.push(quote! { if let #ident::#enum_name(obj) = self { if name == <#p as #crate_name::Type>::type_name() { return #crate_name::collect_fields(ctx, obj, futures); - } #collect_self_fields #collect_parent_interface_fields - return Ok(()); + } else { + return obj.collect_inline_fields(name, pos, ctx, futures); + } } }); @@ -310,7 +283,6 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result #(#possible_types)* possible_types }, - implements: #implements, extends: #extends, keys: None, } diff --git a/src/model/type.rs b/src/model/type.rs index 70b0730a..37dd0bbe 100644 --- a/src/model/type.rs +++ b/src/model/type.rs @@ -130,12 +130,6 @@ impl<'a> __Type<'a> { .map(|ty| __Type::new(self.registry, ty)) .collect(), ) - } else if let TypeDetail::Named(registry::Type::Interface { - implements: Some(implements), - .. - }) = &self.detail - { - Some(vec![__Type::new(self.registry, implements)]) } else { None } diff --git a/src/registry.rs b/src/registry.rs index 599cc44b..3d5eec8d 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -210,7 +210,6 @@ pub enum Type { name: String, description: Option<&'static str>, fields: HashMap, - implements: Option<&'static str>, possible_types: HashSet, extends: bool, keys: Option>, diff --git a/src/schema.rs b/src/schema.rs index 15635488..27e0f2ec 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -38,6 +38,12 @@ pub struct SchemaBuilder(SchemaInner SchemaBuilder { + /// You can use this function to register types that are not directly referenced. + pub fn register_type(mut self) -> Self { + T::create_type_info(&mut self.0.registry); + self + } + /// Disable introspection query pub fn disable_introspection(mut self) -> Self { self.0.query.disable_introspection = true; diff --git a/tests/interface.rs b/tests/interface.rs index 43e21638..93c12150 100644 --- a/tests/interface.rs +++ b/tests/interface.rs @@ -119,7 +119,7 @@ pub async fn test_multiple_interfaces() { #[async_graphql::Interface(field(name = "value_a", type = "i32"))] struct InterfaceA(MyObj); - #[async_graphql::Interface(implements = "InterfaceA", field(name = "value_b", type = "i32"))] + #[async_graphql::Interface(field(name = "value_b", type = "i32"))] struct InterfaceB(MyObj); struct Query; @@ -132,7 +132,9 @@ pub async fn test_multiple_interfaces() { } } - let schema = Schema::new(Query, EmptyMutation, EmptySubscription); + let schema = Schema::build(Query, EmptyMutation, EmptySubscription) + .register_type::() + .finish(); let query = format!( r#"{{ myObj {{