Impl resolve::Value
and resolve::ToInputValue
traits for enums [skip ci]
This commit is contained in:
parent
48631e9b25
commit
7364187437
2 changed files with 202 additions and 5 deletions
|
@ -439,6 +439,16 @@ impl ToTokens for Definition {
|
||||||
self.impl_to_input_value_tokens().to_tokens(into);
|
self.impl_to_input_value_tokens().to_tokens(into);
|
||||||
self.impl_reflection_traits_tokens().to_tokens(into);
|
self.impl_reflection_traits_tokens().to_tokens(into);
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
//self.impl_resolve_type().to_tokens(into);
|
||||||
|
//self.impl_resolve_type_name().to_tokens(into);
|
||||||
|
self.impl_resolve_value().to_tokens(into);
|
||||||
|
self.impl_resolve_value_async().to_tokens(into);
|
||||||
|
self.impl_resolve_to_input_value().to_tokens(into);
|
||||||
|
//self.impl_resolve_input_value().to_tokens(into);
|
||||||
|
//self.impl_resolve_scalar_token().to_tokens(into);
|
||||||
|
//self.impl_graphql_input_type().to_tokens(into);
|
||||||
|
//self.impl_graphql_output_type().to_tokens(into);
|
||||||
|
//self.impl_graphql_enum().to_tokens(into);
|
||||||
self.impl_reflect().to_tokens(into);
|
self.impl_reflect().to_tokens(into);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -602,6 +612,64 @@ impl Definition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns generated code implementing [`resolve::Value`] trait for this
|
||||||
|
/// [GraphQL enum][0].
|
||||||
|
///
|
||||||
|
/// [`resolve::Value`]: juniper::resolve::Value
|
||||||
|
/// [0]: https://spec.graphql.org/October2021#sec-Enums
|
||||||
|
fn impl_resolve_value(&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! {
|
||||||
|
#sv: From<String>
|
||||||
|
});
|
||||||
|
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
|
let variant_arms = self.values.iter().map(|v| {
|
||||||
|
let v_ident = &v.ident;
|
||||||
|
let v_name = &v.name;
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
Self::#v_ident => ::std::result::Result::Ok(
|
||||||
|
::juniper::Value::<#sv>::scalar(
|
||||||
|
::std::string::String::from(#v_name),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let ignored_arm = self.has_ignored_variants.then(|| {
|
||||||
|
let err_msg = format!("Cannot resolve ignored variant of `{}` enum", self.ident);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
_ => ::std::result::Result::Err(
|
||||||
|
::juniper::FieldError::<#sv>::from(#err_msg),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[automatically_derived]
|
||||||
|
impl#impl_gens ::juniper::resolve::Value<#inf, #cx, #sv, #bh>
|
||||||
|
for #ty #where_clause
|
||||||
|
{
|
||||||
|
fn resolve_value(
|
||||||
|
&self,
|
||||||
|
_: Option<&[::juniper::Selection<'_, #sv>]>,
|
||||||
|
_: &#inf,
|
||||||
|
_: &::juniper::Executor<'_, '_, #cx, #sv>,
|
||||||
|
) -> ::juniper::ExecutionResult<#sv> {
|
||||||
|
match self {
|
||||||
|
#( #variant_arms )*
|
||||||
|
#ignored_arm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns generated code implementing [`GraphQLValueAsync`] trait for this
|
/// Returns generated code implementing [`GraphQLValueAsync`] trait for this
|
||||||
/// [GraphQL enum][0].
|
/// [GraphQL enum][0].
|
||||||
///
|
///
|
||||||
|
@ -633,6 +701,48 @@ impl Definition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns generated code implementing [`resolve::ValueAsync`] trait for
|
||||||
|
/// this [GraphQL enum][0].
|
||||||
|
///
|
||||||
|
/// [`resolve::ValueAsync`]: juniper::resolve::ValueAsync
|
||||||
|
/// [0]: https://spec.graphql.org/October2021#sec-Enums
|
||||||
|
fn impl_resolve_value_async(&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);
|
||||||
|
let preds = &mut generics.make_where_clause().predicates;
|
||||||
|
preds.push(parse_quote! {
|
||||||
|
Self: ::juniper::resolve::Value<#inf, #cx, #sv, #bh>
|
||||||
|
});
|
||||||
|
preds.push(parse_quote! {
|
||||||
|
#sv: Send
|
||||||
|
});
|
||||||
|
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[automatically_derived]
|
||||||
|
impl#impl_gens ::juniper::resolve::ValueAsync<#inf, #cx, #sv, #bh>
|
||||||
|
for #ty #where_clause
|
||||||
|
{
|
||||||
|
fn resolve_value_async<'__r>(
|
||||||
|
&'__r self,
|
||||||
|
sel_set: Option<&'__r [::juniper::Selection<'_, #sv>]>,
|
||||||
|
type_info: &'__r #inf,
|
||||||
|
executor: &'__r ::juniper::Executor<'_, '_, #cx, #sv>,
|
||||||
|
) -> ::juniper::BoxFuture<
|
||||||
|
'__r, ::juniper::ExecutionResult<#sv>,
|
||||||
|
> {
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns generated code implementing [`FromInputValue`] trait for this
|
/// Returns generated code implementing [`FromInputValue`] trait for this
|
||||||
/// [GraphQL enum][0].
|
/// [GraphQL enum][0].
|
||||||
///
|
///
|
||||||
|
@ -717,6 +827,53 @@ impl Definition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns generated code implementing [`resolve::ToInputValue`] trait for
|
||||||
|
/// this [GraphQL enum][0].
|
||||||
|
///
|
||||||
|
/// [`resolve::ToInputValue`]: juniper::resolve::ToInputValue
|
||||||
|
/// [0]: https://spec.graphql.org/October2021#sec-Enums
|
||||||
|
fn impl_resolve_to_input_value(&self) -> TokenStream {
|
||||||
|
let bh = &self.behavior;
|
||||||
|
let (ty, generics) = self.ty_and_generics();
|
||||||
|
let (sv, mut generics) = self.mix_scalar_value(generics);
|
||||||
|
generics.make_where_clause().predicates.push(parse_quote! {
|
||||||
|
#sv: From<String>
|
||||||
|
});
|
||||||
|
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
|
let variant_arms = self.values.iter().map(|v| {
|
||||||
|
let v_ident = &v.ident;
|
||||||
|
let v_name = &v.name;
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
Self::#v_ident => ::juniper::graphql::InputValue::<#sv>::scalar(
|
||||||
|
::std::string::String::from(#v_name),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let ignored_arm = self.has_ignored_variants.then(|| {
|
||||||
|
let err_msg = format!("Cannot resolve ignored variant of `{}` enum", self.ident);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
_ => ::std::panic!(#err_msg),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[automatically_derived]
|
||||||
|
impl#impl_gens ::juniper::resolve::ToInputValue<#sv, #bh> for #ty
|
||||||
|
#where_clause
|
||||||
|
{
|
||||||
|
fn to_input_value(&self) -> ::juniper::graphql::InputValue<#sv> {
|
||||||
|
match self {
|
||||||
|
#( #variant_arms )*
|
||||||
|
#ignored_arm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns generated code implementing [`BaseType`], [`BaseSubTypes`] and
|
/// Returns generated code implementing [`BaseType`], [`BaseSubTypes`] and
|
||||||
/// [`WrappedType`] traits for this [GraphQL enum][0].
|
/// [`WrappedType`] traits for this [GraphQL enum][0].
|
||||||
///
|
///
|
||||||
|
@ -860,16 +1017,57 @@ impl Definition {
|
||||||
|
|
||||||
/// Returns prepared self [`syn::Type`] and [`syn::Generics`] for a trait
|
/// Returns prepared self [`syn::Type`] and [`syn::Generics`] for a trait
|
||||||
/// implementation.
|
/// implementation.
|
||||||
#[must_use]
|
|
||||||
fn ty_and_generics(&self) -> (syn::Type, syn::Generics) {
|
fn ty_and_generics(&self) -> (syn::Type, syn::Generics) {
|
||||||
let generics = self.generics.clone();
|
let generics = self.generics.clone();
|
||||||
|
|
||||||
let ty = {
|
let ty = {
|
||||||
let ident = &self.ident;
|
let ident = &self.ident;
|
||||||
let (_, ty_gen, _) = generics.split_for_impl();
|
let (_, ty_gen, _) = generics.split_for_impl();
|
||||||
parse_quote! { #ident#ty_gen }
|
parse_quote! { #ident#ty_gen }
|
||||||
};
|
};
|
||||||
|
|
||||||
(ty, generics)
|
(ty, generics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mixes a type info [`syn::GenericParam`] into the provided
|
||||||
|
/// [`syn::Generics`] and returns its [`syn::Ident`].
|
||||||
|
fn mix_type_info(&self, mut generics: syn::Generics) -> (syn::Ident, syn::Generics) {
|
||||||
|
let ty = parse_quote! { __TypeInfo };
|
||||||
|
generics.params.push(parse_quote! { #ty: ?Sized });
|
||||||
|
(ty, generics)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mixes a context [`syn::GenericParam`] into the provided
|
||||||
|
/// [`syn::Generics`] and returns its [`syn::Ident`].
|
||||||
|
fn mix_context(&self, mut generics: syn::Generics) -> (syn::Ident, syn::Generics) {
|
||||||
|
let ty = parse_quote! { __Context };
|
||||||
|
generics.params.push(parse_quote! { #ty: ?Sized });
|
||||||
|
(ty, generics)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mixes a [`ScalarValue`] [`syn::GenericParam`] into the provided
|
||||||
|
/// [`syn::Generics`] and returns it.
|
||||||
|
///
|
||||||
|
/// [`ScalarValue`]: juniper::ScalarValue
|
||||||
|
fn mix_scalar_value(&self, mut generics: syn::Generics) -> (syn::Ident, syn::Generics) {
|
||||||
|
let sv = parse_quote! { __ScalarValue };
|
||||||
|
generics.params.push(parse_quote! { #sv });
|
||||||
|
(sv, generics)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mixes an [`InputValue`]'s lifetime [`syn::GenericParam`] into the
|
||||||
|
/// provided [`syn::Generics`] and returns it.
|
||||||
|
///
|
||||||
|
/// [`InputValue`]: juniper::resolve::InputValue
|
||||||
|
fn mix_input_lifetime(
|
||||||
|
&self,
|
||||||
|
mut generics: syn::Generics,
|
||||||
|
sv: &syn::Ident,
|
||||||
|
) -> (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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1084,7 +1084,6 @@ impl Definition {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn ty_and_generics(&self) -> (syn::Type, syn::Generics) {
|
fn ty_and_generics(&self) -> (syn::Type, syn::Generics) {
|
||||||
let mut generics = self.generics.clone();
|
let mut generics = self.generics.clone();
|
||||||
|
|
||||||
let ty = {
|
let ty = {
|
||||||
let ident = &self.ident;
|
let ident = &self.ident;
|
||||||
let (_, ty_gen, _) = generics.split_for_impl();
|
let (_, ty_gen, _) = generics.split_for_impl();
|
||||||
|
@ -1248,7 +1247,7 @@ impl Methods {
|
||||||
let into = sv.custom.is_some().then(|| {
|
let into = sv.custom.is_some().then(|| {
|
||||||
quote! { .map_scalar_value() }
|
quote! { .map_scalar_value() }
|
||||||
});
|
});
|
||||||
quote! { Ok(#to_output(self)#into) }
|
quote! { ::std::result::Result::Ok(#to_output(self)#into) }
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::Delegated { field, .. } => {
|
Self::Delegated { field, .. } => {
|
||||||
|
|
Loading…
Reference in a new issue