Add SchemaBuilder::register_type method

This commit is contained in:
sunli 2020-04-21 20:47:48 +08:00
parent 6a3c54613b
commit f7a2fe5fa5
6 changed files with 13 additions and 52 deletions

View File

@ -783,7 +783,6 @@ pub struct Interface {
pub internal: bool,
pub name: Option<String>,
pub desc: Option<String>,
pub implements: Option<String>,
pub fields: Vec<InterfaceField>,
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,
})

View File

@ -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,
}

View File

@ -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
}

View File

@ -210,7 +210,6 @@ pub enum Type {
name: String,
description: Option<&'static str>,
fields: HashMap<String, Field>,
implements: Option<&'static str>,
possible_types: HashSet<String>,
extends: bool,
keys: Option<Vec<String>>,

View File

@ -38,6 +38,12 @@ pub struct SchemaBuilder<Query, Mutation, Subscription>(SchemaInner<Query, Mutat
impl<Query: ObjectType, Mutation: ObjectType, Subscription: SubscriptionType>
SchemaBuilder<Query, Mutation, Subscription>
{
/// You can use this function to register types that are not directly referenced.
pub fn register_type<T: 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;

View File

@ -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::<InterfaceA>()
.finish();
let query = format!(
r#"{{
myObj {{