Add support for generic SimpleObject
. #387
This commit is contained in:
parent
b054fc0704
commit
85a0ab0da1
|
@ -153,7 +153,8 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
||||||
|
|
||||||
let visible = visible_fn(&object_args.visible);
|
let visible = visible_fn(&object_args.visible);
|
||||||
|
|
||||||
let expanded = quote! {
|
let expanded = if object_args.concretes.is_empty() {
|
||||||
|
quote! {
|
||||||
#[allow(clippy::all, clippy::pedantic)]
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
impl #impl_generics #ident #ty_generics #where_clause {
|
impl #impl_generics #ident #ty_generics #where_clause {
|
||||||
#(#getters)*
|
#(#getters)*
|
||||||
|
@ -201,6 +202,77 @@ pub fn generate(object_args: &args::SimpleObject) -> GeneratorResult<TokenStream
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #impl_generics #crate_name::ObjectType for #ident #ty_generics #where_clause {}
|
impl #impl_generics #crate_name::ObjectType for #ident #ty_generics #where_clause {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut code = Vec::new();
|
||||||
|
|
||||||
|
code.push(quote! {
|
||||||
|
impl #impl_generics #ident #ty_generics #where_clause {
|
||||||
|
#(#getters)*
|
||||||
|
|
||||||
|
fn __internal_create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String where Self: #crate_name::OutputType {
|
||||||
|
registry.create_type::<Self, _>(|registry| #crate_name::registry::MetaType::Object {
|
||||||
|
name: ::std::borrow::ToOwned::to_owned(#gql_typename),
|
||||||
|
description: #desc,
|
||||||
|
fields: {
|
||||||
|
let mut fields = #crate_name::indexmap::IndexMap::new();
|
||||||
|
#(#schema_fields)*
|
||||||
|
fields
|
||||||
|
},
|
||||||
|
cache_control: #cache_control,
|
||||||
|
extends: #extends,
|
||||||
|
keys: ::std::option::Option::None,
|
||||||
|
visible: #visible,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn __internal_resolve_field(&self, ctx: &#crate_name::Context<'_>) -> #crate_name::ServerResult<::std::option::Option<#crate_name::Value>> where Self: #crate_name::ContainerType {
|
||||||
|
#(#resolvers)*
|
||||||
|
::std::result::Result::Ok(::std::option::Option::None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for concrete in &object_args.concretes {
|
||||||
|
let gql_typename = &concrete.name;
|
||||||
|
let params = &concrete.params.0;
|
||||||
|
let concrete_type = quote! { #ident<#(#params),*> };
|
||||||
|
|
||||||
|
let expanded = quote! {
|
||||||
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
|
impl #crate_name::Type for #concrete_type {
|
||||||
|
fn type_name() -> ::std::borrow::Cow<'static, ::std::primitive::str> {
|
||||||
|
::std::borrow::Cow::Borrowed(#gql_typename)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_type_info(registry: &mut #crate_name::registry::Registry) -> ::std::string::String {
|
||||||
|
Self::__internal_create_type_info(registry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
|
#[#crate_name::async_trait::async_trait]
|
||||||
|
impl #crate_name::resolver_utils::ContainerType for #concrete_type {
|
||||||
|
async fn resolve_field(&self, ctx: &#crate_name::Context<'_>) -> #crate_name::ServerResult<::std::option::Option<#crate_name::Value>> {
|
||||||
|
self.__internal_resolve_field(ctx).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::all, clippy::pedantic)]
|
||||||
|
#[#crate_name::async_trait::async_trait]
|
||||||
|
impl #crate_name::OutputType for #concrete_type {
|
||||||
|
async fn resolve(&self, ctx: &#crate_name::ContextSelectionSet<'_>, _field: &#crate_name::Positioned<#crate_name::parser::types::Field>) -> #crate_name::ServerResult<#crate_name::Value> {
|
||||||
|
#crate_name::resolver_utils::resolve_container(ctx, self).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl #crate_name::ObjectType for #concrete_type {}
|
||||||
};
|
};
|
||||||
|
code.push(expanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
quote!(#(#code)*)
|
||||||
|
};
|
||||||
|
|
||||||
Ok(expanded.into())
|
Ok(expanded.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,12 +90,42 @@ pub async fn test_input_object_generic() {
|
||||||
#[async_std::test]
|
#[async_std::test]
|
||||||
pub async fn test_generic_simple_object() {
|
pub async fn test_generic_simple_object() {
|
||||||
#[derive(SimpleObject)]
|
#[derive(SimpleObject)]
|
||||||
#[graphql(
|
#[graphql(concrete(name = "MyObjIntString", params(i32, String)))]
|
||||||
concrete(name = "IntEqualityFilter", params(i32)),
|
#[graphql(concrete(name = "MyObji64f32", params(i64, u8)))]
|
||||||
concrete(name = "StringEqualityFilter", params(String))
|
|
||||||
)]
|
|
||||||
struct MyObj<A: OutputType, B: OutputType> {
|
struct MyObj<A: OutputType, B: OutputType> {
|
||||||
a: A,
|
a: A,
|
||||||
b: B,
|
b: B,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Query;
|
||||||
|
|
||||||
|
#[Object]
|
||||||
|
impl Query {
|
||||||
|
async fn q1(&self) -> MyObj<i32, String> {
|
||||||
|
MyObj {
|
||||||
|
a: 100,
|
||||||
|
b: "abc".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn q2(&self) -> MyObj<i64, u8> {
|
||||||
|
MyObj { a: 100, b: 28 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
|
||||||
|
let query = "{ q1 { a b } q2 { a b } }";
|
||||||
|
assert_eq!(
|
||||||
|
schema.execute(query).await.into_result().unwrap().data,
|
||||||
|
value!({
|
||||||
|
"q1": {
|
||||||
|
"a": 100,
|
||||||
|
"b": "abc",
|
||||||
|
},
|
||||||
|
"q2": {
|
||||||
|
"a": 100,
|
||||||
|
"b": 28,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user