Impl macro for scalars, vol.6 [skip ci]
This commit is contained in:
parent
4d7770d226
commit
66c11ec782
1 changed files with 121 additions and 46 deletions
|
@ -358,14 +358,14 @@ impl ToTokens for Definition {
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
self.impl_resolve_type().to_tokens(into);
|
self.impl_resolve_type().to_tokens(into);
|
||||||
self.impl_resolve_type_name().to_tokens(into);
|
self.impl_resolve_type_name().to_tokens(into);
|
||||||
//self.impl_resolve_value().to_tokens(into);
|
self.impl_resolve_value().to_tokens(into);
|
||||||
//self.impl_resolve_value_async().to_tokens(into);
|
self.impl_resolve_value_async().to_tokens(into);
|
||||||
self.impl_resolve_to_input_value().to_tokens(into);
|
self.impl_resolve_to_input_value().to_tokens(into);
|
||||||
self.impl_resolve_input_value().to_tokens(into);
|
self.impl_resolve_input_value().to_tokens(into);
|
||||||
self.impl_resolve_scalar_token().to_tokens(into);
|
self.impl_resolve_scalar_token().to_tokens(into);
|
||||||
//self.impl_graphql_output_type().to_tokens(into);
|
self.impl_graphql_input_type().to_tokens(into);
|
||||||
//self.impl_graphql_output_type().to_tokens(into);
|
self.impl_graphql_output_type().to_tokens(into);
|
||||||
//self.impl_graphql_scalar().to_tokens(into);
|
self.impl_graphql_scalar().to_tokens(into);
|
||||||
self.impl_reflect().to_tokens(into);
|
self.impl_reflect().to_tokens(into);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,29 +395,58 @@ impl Definition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns generated code implementing [`graphql::InputType`] and
|
/// Returns generated code implementing [`graphql::InputType`] trait for
|
||||||
/// [`graphql::OutputType`] traits for this [GraphQL scalar][0].
|
/// this [GraphQL scalar][0].
|
||||||
///
|
///
|
||||||
/// [`graphql::InputType`]: juniper::graphql::InputType
|
/// [`graphql::InputType`]: juniper::graphql::InputType
|
||||||
/// [`graphql::OutputType`]: juniper::graphql::OutputType
|
|
||||||
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn impl_graphql_input_and_output_type(&self) -> TokenStream {
|
fn impl_graphql_input_type(&self) -> TokenStream {
|
||||||
|
let bh = &self.behavior;
|
||||||
let (ty, generics) = self.ty_and_generics();
|
let (ty, generics) = self.ty_and_generics();
|
||||||
|
let (inf, generics) = self.mix_type_info(generics);
|
||||||
let (sv, generics) = self.mix_scalar_value(generics);
|
let (sv, generics) = self.mix_scalar_value(generics);
|
||||||
|
let (lt, mut generics) = self.mix_input_lifetime(generics, sv);
|
||||||
|
generics.make_where_clause().predicates.push(parse_quote! {
|
||||||
|
Self: ::juniper::resolve::Type<#inf, #sv, #bh>
|
||||||
|
+ ::juniper::resolve::ToInputValue<#sv, #bh>
|
||||||
|
+ ::juniper::resolve::InputValue<#lt, #sv, #bh>
|
||||||
|
});
|
||||||
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl#impl_gens ::juniper::graphql::InputType<#sv> for #ty
|
impl#impl_gens ::juniper::graphql::InputType<#lt, #inf, #sv, #bh>
|
||||||
#where_clause
|
for #ty #where_clause
|
||||||
{
|
{
|
||||||
fn assert_input_type() {}
|
fn assert_input_type() {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns generated code implementing [`graphql::OutputType`] trait for
|
||||||
|
/// this [GraphQL scalar][0].
|
||||||
|
///
|
||||||
|
/// [`graphql::OutputType`]: juniper::graphql::OutputType
|
||||||
|
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
||||||
|
#[must_use]
|
||||||
|
fn impl_graphql_output_type(&self) -> TokenStream {
|
||||||
|
let bh = &self.behavior;
|
||||||
|
let (ty, generics) = self.ty_and_generics();
|
||||||
|
let (inf, generics) = self.mix_type_info(generics);
|
||||||
|
let (cx, generics) = self.mix_context(generics);
|
||||||
|
let (sv, mut generics) = self.mix_scalar_value(generics);
|
||||||
|
generics.make_where_clause().predicates.push(parse_quote! {
|
||||||
|
Self: ::juniper::resolve::Type<#inf, #sv, #bh>
|
||||||
|
+ ::juniper::resolve::Value<#inf, #cx, #sv, #bh>
|
||||||
|
+ ::juniper::resolve::ValueAsync<#inf, #cx, #sv, #bh>
|
||||||
|
});
|
||||||
|
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
|
quote! {
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl#impl_gens ::juniper::graphql::OutputType<#sv> for #ty
|
impl#impl_gens ::juniper::graphql::OutputType<#inf, #cx, #sv, #bh>
|
||||||
#where_clause
|
for #ty #where_clause
|
||||||
{
|
{
|
||||||
fn assert_output_type() {}
|
fn assert_output_type() {}
|
||||||
}
|
}
|
||||||
|
@ -431,14 +460,23 @@ impl Definition {
|
||||||
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn impl_graphql_scalar(&self) -> TokenStream {
|
fn impl_graphql_scalar(&self) -> TokenStream {
|
||||||
|
let bh = &self.behavior;
|
||||||
let (ty, generics) = self.ty_and_generics();
|
let (ty, generics) = self.ty_and_generics();
|
||||||
|
let (inf, generics) = self.mix_type_info(generics);
|
||||||
|
let (cx, generics) = self.mix_context(generics);
|
||||||
let (sv, generics) = self.mix_scalar_value(generics);
|
let (sv, generics) = self.mix_scalar_value(generics);
|
||||||
|
let (lt, mut generics) = self.mix_input_lifetime(generics, sv);
|
||||||
|
generics.make_where_clause().predicates.push(parse_quote! {
|
||||||
|
Self: ::juniper::graphql::InputType<#lt, #inf, #sv, #bh>
|
||||||
|
+ ::juniper::graphql::OutputType<#inf, #cx, #sv, #bh>
|
||||||
|
+ ::juniper::resolve::ScalarToken<#sv, #bh>
|
||||||
|
});
|
||||||
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl#impl_gens ::juniper::graphql::Scalar<#sv> for #ty
|
impl#impl_gens ::juniper::graphql::Scalar<#lt, #inf, #cx, #sv, #bh>
|
||||||
#where_clause
|
for #ty #where_clause
|
||||||
{
|
{
|
||||||
fn assert_scalar() {}
|
fn assert_scalar() {}
|
||||||
}
|
}
|
||||||
|
@ -524,9 +562,9 @@ impl Definition {
|
||||||
let (ty, generics) = self.ty_and_generics();
|
let (ty, generics) = self.ty_and_generics();
|
||||||
let (inf, generics) = self.mix_type_info(generics);
|
let (inf, generics) = self.mix_type_info(generics);
|
||||||
let (sv, mut generics) = self.mix_scalar_value(generics);
|
let (sv, mut generics) = self.mix_scalar_value(generics);
|
||||||
let predicates = &mut generics.make_where_clause().predicates;
|
let preds = &mut generics.make_where_clause().predicates;
|
||||||
predicates.push(parse_quote! { #sv: Clone });
|
preds.push(parse_quote! { #sv: Clone });
|
||||||
predicates.push(parse_quote! {
|
preds.push(parse_quote! {
|
||||||
::juniper::behavior::Coerce<Self>:
|
::juniper::behavior::Coerce<Self>:
|
||||||
::juniper::resolve::TypeName<#inf>
|
::juniper::resolve::TypeName<#inf>
|
||||||
+ ::juniper::resolve::ScalarToken<#sv>
|
+ ::juniper::resolve::ScalarToken<#sv>
|
||||||
|
@ -610,6 +648,7 @@ impl Definition {
|
||||||
/// [`resolve::Value`]: juniper::resolve::Value
|
/// [`resolve::Value`]: juniper::resolve::Value
|
||||||
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
||||||
fn impl_resolve_value(&self) -> TokenStream {
|
fn impl_resolve_value(&self) -> TokenStream {
|
||||||
|
let bh = &self.behavior;
|
||||||
let (ty, generics) = self.ty_and_generics();
|
let (ty, generics) = self.ty_and_generics();
|
||||||
let (inf, generics) = self.mix_type_info(generics);
|
let (inf, generics) = self.mix_type_info(generics);
|
||||||
let (cx, generics) = self.mix_context(generics);
|
let (cx, generics) = self.mix_context(generics);
|
||||||
|
@ -617,20 +656,20 @@ impl Definition {
|
||||||
generics
|
generics
|
||||||
.make_where_clause()
|
.make_where_clause()
|
||||||
.predicates
|
.predicates
|
||||||
.push(self.methods.bound_resolve_value(&inf, &cx, sv));
|
.extend(self.methods.bound_resolve_value(&inf, &cx, sv));
|
||||||
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
let body = self.methods.expand_resolve_value(&inf, &cx, sv);
|
let body = self.methods.expand_resolve_value(&inf, &cx, sv);
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl#impl_gens ::juniper::resolve::Value<#inf, #cx, #sv> for #ty
|
impl#impl_gens ::juniper::resolve::Value<#inf, #cx, #sv, #bh>
|
||||||
#where_clause
|
for #ty #where_clause
|
||||||
{
|
{
|
||||||
fn resolve_value(
|
fn resolve_value(
|
||||||
&self,
|
&self,
|
||||||
selection: Option<&[::juniper::Selection<'_, #sv>]>,
|
selection_set: Option<&[::juniper::Selection<'_, #sv>]>,
|
||||||
info: &#inf,
|
type_info: &#inf,
|
||||||
executor: &::juniper::Executor<'_, '_, #cx, #sv>,
|
executor: &::juniper::Executor<'_, '_, #cx, #sv>,
|
||||||
) -> ::juniper::ExecutionResult<#sv> {
|
) -> ::juniper::ExecutionResult<#sv> {
|
||||||
#body
|
#body
|
||||||
|
@ -675,13 +714,14 @@ impl Definition {
|
||||||
/// [`resolve::ValueAsync`]: juniper::resolve::ValueAsync
|
/// [`resolve::ValueAsync`]: juniper::resolve::ValueAsync
|
||||||
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
||||||
fn impl_resolve_value_async(&self) -> TokenStream {
|
fn impl_resolve_value_async(&self) -> TokenStream {
|
||||||
|
let bh = &self.behavior;
|
||||||
let (ty, generics) = self.ty_and_generics();
|
let (ty, generics) = self.ty_and_generics();
|
||||||
let (inf, generics) = self.mix_type_info(generics);
|
let (inf, generics) = self.mix_type_info(generics);
|
||||||
let (cx, generics) = self.mix_context(generics);
|
let (cx, generics) = self.mix_context(generics);
|
||||||
let (sv, mut generics) = self.mix_scalar_value(generics);
|
let (sv, mut generics) = self.mix_scalar_value(generics);
|
||||||
let preds = &mut generics.make_where_clause().predicates;
|
let preds = &mut generics.make_where_clause().predicates;
|
||||||
preds.push(parse_quote! {
|
preds.push(parse_quote! {
|
||||||
Self: ::juniper::resolve::Value<#inf, #cx, #sv>
|
Self: ::juniper::resolve::Value<#inf, #cx, #sv, #bh>
|
||||||
});
|
});
|
||||||
preds.push(parse_quote! {
|
preds.push(parse_quote! {
|
||||||
#sv: Send
|
#sv: Send
|
||||||
|
@ -690,17 +730,20 @@ impl Definition {
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl#impl_gens ::juniper::resolve::ValueAsync<#inf, #cx, #sv> for #ty
|
impl#impl_gens ::juniper::resolve::ValueAsync<#inf, #cx, #sv, #bh>
|
||||||
#where_clause
|
for #ty #where_clause
|
||||||
{
|
{
|
||||||
fn resolve_value_async<'__r>(
|
fn resolve_value_async<'__r>(
|
||||||
&'__r self,
|
&'__r self,
|
||||||
selection: Option<&'__r [::juniper::Selection<'_, #sv>]>,
|
sel_set: Option<&'__r [::juniper::Selection<'_, #sv>]>,
|
||||||
info: &'__r #inf,
|
type_info: &'__r #inf,
|
||||||
executor: &'__r ::juniper::Executor<'_, '_, #cx, #sv>,
|
executor: &'__r ::juniper::Executor<'_, '_, #cx, #sv>,
|
||||||
) -> ::juniper::BoxFuture<'__r, ::juniper::ExecutionResult<#sv>> {
|
) -> ::juniper::BoxFuture<
|
||||||
let v = <Self as ::juniper::resolve::Value<#inf, #cx, #sv>>
|
'__r, ::juniper::ExecutionResult<#sv>,
|
||||||
::resolve_value(self, selection, info, executor);
|
> {
|
||||||
|
let v =
|
||||||
|
<Self as ::juniper::resolve::Value<#inf, #cx, #sv, #bh>>
|
||||||
|
::resolve_value(self, sel_set, type_info, executor);
|
||||||
::std::boxed::Box::pin(::juniper::futures::future::ready(v))
|
::std::boxed::Box::pin(::juniper::futures::future::ready(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -797,12 +840,12 @@ impl Definition {
|
||||||
fn impl_resolve_input_value(&self) -> TokenStream {
|
fn impl_resolve_input_value(&self) -> TokenStream {
|
||||||
let bh = &self.behavior;
|
let bh = &self.behavior;
|
||||||
let (ty, generics) = self.ty_and_generics();
|
let (ty, generics) = self.ty_and_generics();
|
||||||
let (sv, mut generics) = self.mix_scalar_value(generics);
|
let (sv, generics) = self.mix_scalar_value(generics);
|
||||||
let lt: syn::GenericParam = parse_quote! { '__inp };
|
let (lt, mut generics) = self.mix_input_lifetime(generics, sv);
|
||||||
generics.params.push(lt.clone());
|
generics
|
||||||
let predicates = &mut generics.make_where_clause().predicates;
|
.make_where_clause()
|
||||||
predicates.push(parse_quote! { #sv: #lt });
|
.predicates
|
||||||
predicates.extend(self.methods.bound_try_from_input_value(<, sv));
|
.extend(self.methods.bound_try_from_input_value(<, sv));
|
||||||
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
let error_ty = self.methods.expand_try_from_input_value_error(<, sv);
|
let error_ty = self.methods.expand_try_from_input_value_error(<, sv);
|
||||||
|
@ -1090,6 +1133,25 @@ impl Definition {
|
||||||
generics.params.push(parse_quote! { #sv });
|
generics.params.push(parse_quote! { #sv });
|
||||||
(sv, generics)
|
(sv, generics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mixes an [`InputValue`]'s lifetime [`syn::GenericParam`] into the
|
||||||
|
/// provided [`syn::Generics`] and returns it.
|
||||||
|
///
|
||||||
|
/// [`InputValue`]: juniper::resolve::InputValue
|
||||||
|
#[must_use]
|
||||||
|
fn mix_input_lifetime(
|
||||||
|
&self,
|
||||||
|
mut generics: syn::Generics,
|
||||||
|
sv: &ScalarValue,
|
||||||
|
) -> (syn::GenericParam, syn::Generics) {
|
||||||
|
let lt: syn::GenericParam = parse_quote! { '__inp };
|
||||||
|
generics.params.push(lt.clone());
|
||||||
|
generics
|
||||||
|
.make_where_clause()
|
||||||
|
.predicates
|
||||||
|
.push(parse_quote! { #sv: #lt });
|
||||||
|
(lt, generics)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds `__fa__` prefix to all lifetimes to avoid "lifetime name `'a` shadows a
|
/// Adds `__fa__` prefix to all lifetimes to avoid "lifetime name `'a` shadows a
|
||||||
|
@ -1183,18 +1245,23 @@ impl Methods {
|
||||||
to_output: Some(to_output),
|
to_output: Some(to_output),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
quote! { Ok(#to_output(self)) }
|
let into = sv.custom.is_some().then(|| {
|
||||||
|
quote! { .map_scalar_value() }
|
||||||
|
});
|
||||||
|
quote! { Ok(#to_output(self)#into) }
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::Delegated { field, .. } => {
|
Self::Delegated { field, .. } => {
|
||||||
let field_ty = field.ty();
|
let field_ty = field.ty();
|
||||||
|
let field_bh = &field.behavior;
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
<#field_ty as ::juniper::resolve::Value<#inf, #cx, #sv>>
|
<#field_ty as
|
||||||
|
::juniper::resolve::Value<#inf, #cx, #sv, #field_bh>>
|
||||||
::resolve_value(
|
::resolve_value(
|
||||||
&self.#field,
|
&self.#field,
|
||||||
info,
|
selection_set,
|
||||||
selection,
|
type_info,
|
||||||
executor,
|
executor,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1212,23 +1279,31 @@ impl Methods {
|
||||||
inf: &syn::Ident,
|
inf: &syn::Ident,
|
||||||
cx: &syn::Ident,
|
cx: &syn::Ident,
|
||||||
sv: &ScalarValue,
|
sv: &ScalarValue,
|
||||||
) -> syn::WherePredicate {
|
) -> Vec<syn::WherePredicate> {
|
||||||
match self {
|
match self {
|
||||||
Self::Custom { .. }
|
Self::Custom { .. }
|
||||||
| Self::Delegated {
|
| Self::Delegated {
|
||||||
to_output: Some(_), ..
|
to_output: Some(_), ..
|
||||||
} => {
|
} => {
|
||||||
parse_quote! {
|
let mut bounds = vec![parse_quote! {
|
||||||
#sv: ::juniper::ScalarValue
|
#sv: ::juniper::ScalarValue
|
||||||
|
}];
|
||||||
|
if let Some(custom_sv) = &sv.custom {
|
||||||
|
bounds.push(parse_quote! {
|
||||||
|
#custom_sv: ::juniper::ScalarValue
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::Delegated { field, .. } => {
|
Self::Delegated { field, .. } => {
|
||||||
let field_ty = field.ty();
|
let field_ty = field.ty();
|
||||||
|
let field_bh = &field.behavior;
|
||||||
|
|
||||||
parse_quote! {
|
vec![parse_quote! {
|
||||||
#field_ty: ::juniper::resolve::Value<#inf, #cx, #sv>
|
#field_ty:
|
||||||
}
|
::juniper::resolve::Value<#inf, #cx, #sv, #field_bh>
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue