From b1be8f1d29cdfb640ef1bfd4e205ac4a7798382f Mon Sep 17 00:00:00 2001 From: tyranron <tyranron@gmail.com> Date: Mon, 30 May 2022 19:09:15 +0200 Subject: [PATCH] Improve codegen for scalars, vol.2 --- juniper/src/lib.rs | 1 + juniper/src/reflect/mod.rs | 1 + juniper/src/types/scalars.rs | 12 --- juniper/src/types/str.rs | 18 ++++- juniper_codegen/src/graphql_scalar/mod.rs | 93 ++++++++++++++++++----- 5 files changed, 90 insertions(+), 35 deletions(-) create mode 100644 juniper/src/reflect/mod.rs diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index 6e35d230..9340608a 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -36,6 +36,7 @@ pub mod http; pub mod integrations; mod introspection; pub mod parser; +pub mod reflect; pub mod resolve; pub(crate) mod schema; mod types; diff --git a/juniper/src/reflect/mod.rs b/juniper/src/reflect/mod.rs new file mode 100644 index 00000000..e91f009a --- /dev/null +++ b/juniper/src/reflect/mod.rs @@ -0,0 +1 @@ +pub use crate::macros::reflect::*; diff --git a/juniper/src/types/scalars.rs b/juniper/src/types/scalars.rs index 66e26e74..ac781770 100644 --- a/juniper/src/types/scalars.rs +++ b/juniper/src/types/scalars.rs @@ -196,18 +196,6 @@ where }) } -impl<S> reflect::WrappedType<S> for str { - const VALUE: reflect::WrappedValue = 1; -} - -impl<S> reflect::BaseType<S> for str { - const NAME: reflect::Type = "String"; -} - -impl<S> reflect::BaseSubTypes<S> for str { - const NAMES: reflect::Types = &[<Self as reflect::BaseType<S>>::NAME]; -} - impl<S> GraphQLType<S> for str where S: ScalarValue, diff --git a/juniper/src/types/str.rs b/juniper/src/types/str.rs index af7c966c..24861e6b 100644 --- a/juniper/src/types/str.rs +++ b/juniper/src/types/str.rs @@ -7,7 +7,7 @@ use std::{rc::Rc, sync::Arc}; use futures::future; use crate::{ - graphql, + graphql, reflect, meta::MetaType, parser::{ParseError, ScalarToken}, resolve, BoxFuture, ExecutionResult, Executor, Registry, ScalarValue, Selection, @@ -25,8 +25,8 @@ impl<Info: ?Sized, S: ScalarValue> resolve::Type<Info, S> for str { } impl<Info: ?Sized> resolve::TypeName<Info> for str { - fn type_name(info: &Info) -> &str { - <String as resolve::TypeName<Info>>::type_name(info) + fn type_name(_: &Info) -> &'static str { + <Self as reflect::BaseType<()>>::NAME } } @@ -119,3 +119,15 @@ impl<S> graphql::OutputType<S> for str { impl<S> graphql::Scalar<S> for str { fn assert_scalar() {} } + +impl<S> reflect::BaseType<S> for str { + const NAME: reflect::Type = <String as reflect::BaseType<S>>::NAME; +} + +impl<S> reflect::BaseSubTypes<S> for str { + const NAMES: reflect::Types = &[<Self as reflect::BaseType<S>>::NAME]; +} + +impl<S> reflect::WrappedType<S> for str { + const VALUE: reflect::WrappedValue = 1; +} diff --git a/juniper_codegen/src/graphql_scalar/mod.rs b/juniper_codegen/src/graphql_scalar/mod.rs index 45a34291..7e98eae3 100644 --- a/juniper_codegen/src/graphql_scalar/mod.rs +++ b/juniper_codegen/src/graphql_scalar/mod.rs @@ -329,12 +329,14 @@ impl ToTokens for Definition { self.impl_to_input_value_tokens().to_tokens(into); self.impl_from_input_value_tokens().to_tokens(into); self.impl_parse_scalar_value_tokens().to_tokens(into); - self.impl_reflection_traits_tokens().to_tokens(into); //////////////////////////////////////////////////////////////////////// - self.impl_resolve_type_name().to_tokens(into); self.impl_resolve_type().to_tokens(into); + self.impl_resolve_type_name().to_tokens(into); self.impl_resolve_input_value().to_tokens(into); self.impl_resolve_scalar_token().to_tokens(into); + self.impl_input_and_output_type().to_tokens(into); + //self.impl_scalar().to_tokens(into); + self.impl_reflect().to_tokens(into); } } @@ -363,6 +365,56 @@ impl Definition { } } + /// Returns generated code implementing [`graphql::InputType`] and + /// [`graphql::OutputType`] traits for this [GraphQL scalar][0]. + /// + /// [`graphql::InputType`]: juniper::graphql::InputType + /// [`graphql::OutputType`]: juniper::graphql::OutputType + /// [0]: https://spec.graphql.org/October2021#sec-Scalars + #[must_use] + fn impl_input_and_output_type(&self) -> TokenStream { + let (ty, generics) = self.ty_and_generics(); + let (scalar, generics) = self.mix_scalar(generics); + let (impl_gens, _, where_clause) = generics.split_for_impl(); + + quote! { + #[automatically_derived] + impl#impl_gens ::juniper::graphql::InputType<#scalar> for #ty + #where_clause + { + fn assert_input_type() {} + } + + #[automatically_derived] + impl#impl_gens ::juniper::graphql::OutputType<#scalar> for #ty + #where_clause + { + fn assert_output_type() {} + } + } + } + + /// Returns generated code implementing [`graphql::Scalar`] trait for this + /// [GraphQL scalar][0]. + /// + /// [`graphql::Scalar`]: juniper::graphql::Scalar + /// [0]: https://spec.graphql.org/October2021#sec-Scalars + #[must_use] + fn impl_scalar(&self) -> TokenStream { + let (ty, generics) = self.ty_and_generics(); + let (scalar, generics) = self.mix_scalar(generics); + let (impl_gens, _, where_clause) = generics.split_for_impl(); + + quote! { + #[automatically_derived] + impl#impl_gens ::juniper::graphql::Scalar<#scalar> for #ty + #where_clause + { + fn assert_scalar() {} + } + } + } + /// Returns generated code implementing [`GraphQLType`] trait for this /// [GraphQL scalar][1]. /// @@ -696,41 +748,42 @@ impl Definition { } } - /// Returns generated code implementing [`BaseType`], [`BaseSubTypes`] and - /// [`WrappedType`] traits for this [GraphQL scalar][1]. + /// Returns generated code implementing [`reflect::BaseType`], + /// [`reflect::BaseSubTypes`] and [`reflect::WrappedType`] traits for this + /// [GraphQL scalar][0]. /// - /// [`BaseSubTypes`]: juniper::macros::reflection::BaseSubTypes - /// [`BaseType`]: juniper::macros::reflection::BaseType - /// [`WrappedType`]: juniper::macros::reflection::WrappedType - /// [1]: https://spec.graphql.org/October2021#sec-Scalars - fn impl_reflection_traits_tokens(&self) -> TokenStream { - let scalar = &self.scalar; - let name = &self.name; - - let (ty, generics) = self.impl_self_and_generics(false); + /// [`reflect::BaseSubTypes`]: juniper::reflection::BaseSubTypes + /// [`reflect::BaseType`]: juniper::reflection::BaseType + /// [`reflect::WrappedType`]: juniper::reflection::WrappedType + /// [0]: https://spec.graphql.org/October2021#sec-Scalars + fn impl_reflect(&self) -> TokenStream { + let (ty, generics) = self.ty_and_generics(); + let (scalar, generics) = self.mix_scalar(generics); let (impl_gens, _, where_clause) = generics.split_for_impl(); + let name = &self.name; + quote! { #[automatically_derived] - impl#impl_gens ::juniper::macros::reflect::BaseType<#scalar> for #ty + impl#impl_gens ::juniper::reflect::BaseType<#scalar> for #ty #where_clause { - const NAME: ::juniper::macros::reflect::Type = #name; + const NAME: ::juniper::reflect::Type = #name; } #[automatically_derived] - impl#impl_gens ::juniper::macros::reflect::BaseSubTypes<#scalar> for #ty + impl#impl_gens ::juniper::reflect::BaseSubTypes<#scalar> for #ty #where_clause { - const NAMES: ::juniper::macros::reflect::Types = - &[<Self as ::juniper::macros::reflect::BaseType<#scalar>>::NAME]; + const NAMES: ::juniper::reflect::Types = + &[<Self as ::juniper::reflect::BaseType<#scalar>>::NAME]; } #[automatically_derived] - impl#impl_gens ::juniper::macros::reflect::WrappedType<#scalar> for #ty + impl#impl_gens ::juniper::reflect::WrappedType<#scalar> for #ty #where_clause { - const VALUE: ::juniper::macros::reflect::WrappedValue = 1; + const VALUE: ::juniper::reflect::WrappedValue = 1; } } }