Fix interface resolver bug

This commit is contained in:
sunli 2020-04-22 14:59:14 +08:00
parent 4ba2985ba4
commit 279244d106
5 changed files with 20 additions and 30 deletions

View File

@ -67,11 +67,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
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);
} else {
return obj.collect_inline_fields(name, pos, ctx, futures);
}
return obj.collect_inline_fields(name, pos, ctx, futures);
}
});
@ -309,10 +305,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
futures: &mut Vec<#crate_name::BoxFieldFuture<'a>>,
) -> #crate_name::Result<()> {
#(#collect_inline_fields)*
Err(#crate_name::QueryError::UnrecognizedInlineFragment {
object: #gql_typename.to_string(),
name: name.to_string(),
}.into_error(pos))
Ok(())
}
}

View File

@ -56,11 +56,8 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
possible_types.insert(<#p as #crate_name::Type>::type_name().to_string());
});
collect_inline_fields.push(quote! {
if name == <#p as #crate_name::Type>::type_name() {
if let #ident::#enum_name(obj) = self {
return #crate_name::collect_fields(ctx, obj, futures);
}
return Ok(());
if let #ident::#enum_name(obj) = self {
return obj.collect_inline_fields(name, pos, ctx, futures);
}
});
get_introspection_typename.push(quote! {
@ -122,10 +119,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
futures: &mut Vec<#crate_name::BoxFieldFuture<'a>>,
) -> #crate_name::Result<()> {
#(#collect_inline_fields)*
Err(#crate_name::QueryError::UnrecognizedInlineFragment {
object: #gql_typename.to_string(),
name: name.to_string(),
}.into_error(pos))
Ok(())
}
}

View File

@ -82,7 +82,7 @@ pub trait ObjectType: OutputValueType {
/// Collect the fields with the `name` inline object
fn collect_inline_fields<'a>(
&'a self,
_name: &str,
name: &str,
_pos: Pos,
ctx: &ContextSelectionSet<'a>,
futures: &mut Vec<BoxFieldFuture<'a>>,
@ -90,7 +90,19 @@ pub trait ObjectType: OutputValueType {
where
Self: Send + Sync + Sized,
{
crate::collect_fields(ctx, self, futures)
if name == Self::type_name().as_ref() {
crate::collect_fields(ctx, self, futures)
} else if ctx
.registry
.implements
.get(Self::type_name().as_ref())
.map(|ty| ty.contains(name))
.unwrap_or_default()
{
crate::collect_fields(ctx, self, futures)
} else {
Ok(())
}
}
/// Query entities with params

View File

@ -236,15 +236,6 @@ pub enum QueryError {
interface: String,
},
#[error("Unrecognized inline fragment \"{name}\" on type \"{object}\"")]
UnrecognizedInlineFragment {
/// Object name
object: String,
/// Inline fragment name
name: String,
},
#[error("Too complex")]
TooComplex,

View File

@ -211,7 +211,7 @@ pub async fn test_multiple_interfaces() {
}
let schema = Schema::build(Query, EmptyMutation, EmptySubscription)
.register_type::<InterfaceB>() // `InterfaceA` is not directly referenced, so manual registration is required.
.register_type::<InterfaceB>() // `InterfaceB` is not directly referenced, so manual registration is required.
.finish();
let query = format!(
r#"{{