Skip to content

Commit 42cd004

Browse files
committed
(codegen) Improve generics support for impl_object macro
1 parent d786ffa commit 42cd004

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

integration_tests/juniper_tests/src/codegen/impl_object.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct Context {
1111
version: Option<String>,
1212
}
1313

14+
1415
#[derive(Default)]
1516
struct TheQuery {
1617
b: bool,

juniper_codegen/src/impl_object.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ pub fn build(args: TokenStream, body: TokenStream) -> TokenStream {
168168
scalar: impl_attrs.scalar,
169169
description: impl_attrs.description,
170170
fields: Vec::new(),
171+
generics: _impl.generics.clone(),
171172
};
172173

173174
for item in &mut _impl.items {
@@ -274,7 +275,7 @@ pub fn build(args: TokenStream, body: TokenStream) -> TokenStream {
274275
}
275276
}
276277

277-
let graphql_type_impl = definition.to_tokens();
278+
let graphql_type_impl = definition.into_tokens();
278279
let body = quote!(
279280
#_impl
280281
#graphql_type_impl

juniper_codegen/src/util.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,11 @@ pub struct GraphQLTypeDefiniton {
273273
pub scalar: Option<syn::Type>,
274274
pub description: Option<String>,
275275
pub fields: Vec<GraphQLTypeDefinitionField>,
276+
pub generics: syn::Generics,
276277
}
277278

278279
impl GraphQLTypeDefiniton {
279-
pub fn to_tokens(&self) -> proc_macro2::TokenStream {
280+
pub fn into_tokens(self) -> proc_macro2::TokenStream {
280281
let name = &self.name;
281282
let ty = &self._type;
282283
let context = self
@@ -347,8 +348,36 @@ impl GraphQLTypeDefiniton {
347348
None => quote!(),
348349
};
349350

351+
352+
let (_, ty_generics, _) = self.generics.split_for_impl();
353+
354+
let mut generics = self.generics.clone();
355+
356+
if self.scalar.is_none() {
357+
generics.params.push(parse_quote!(__S));
358+
{
359+
let where_clause = generics.where_clause.get_or_insert(parse_quote!(where));
360+
where_clause
361+
.predicates
362+
.push(parse_quote!(__S: juniper::ScalarValue));
363+
where_clause
364+
.predicates
365+
.push(parse_quote!(for<'__b> &'__b __S: juniper::ScalarRefValue<'__b>));
366+
}
367+
}
368+
369+
let scalar = self
370+
.scalar
371+
.as_ref()
372+
.map(|s| quote!( #s ))
373+
.unwrap_or_else(|| quote!( __S ));
374+
375+
let (impl_generics, _, where_clause) = generics.split_for_impl();
376+
350377
quote!(
351-
impl juniper::GraphQLType<#scalar> for #ty {
378+
impl#impl_generics juniper::GraphQLType<#scalar> for #ty #ty_generics
379+
#where_clause
380+
{
352381
type Context = #context;
353382
type TypeInfo = ();
354383

@@ -361,7 +390,7 @@ impl GraphQLTypeDefiniton {
361390
registry: &mut juniper::Registry<'r, #scalar>
362391
) -> juniper::meta::MetaType<'r, #scalar>
363392
where #scalar : 'r,
364-
for<'z> &'z juniper::DefaultScalarValue: juniper::ScalarRefValue<'z>,
393+
// for<'z> &'z juniper::DefaultScalarValue: juniper::ScalarRefValue<'z>,
365394
{
366395
let fields = vec![
367396
#( #field_definitions ),*
@@ -377,9 +406,9 @@ impl GraphQLTypeDefiniton {
377406
&self,
378407
_info: &(),
379408
field: &str,
380-
args: &juniper::Arguments,
381-
executor: &juniper::Executor<Self::Context>,
382-
) -> juniper::ExecutionResult {
409+
args: &juniper::Arguments<#scalar>,
410+
executor: &juniper::Executor<Self::Context, #scalar>,
411+
) -> juniper::ExecutionResult<#scalar> {
383412
match field {
384413
#( #resolve_matches )*
385414
_ => {

0 commit comments

Comments
 (0)