From 5a62ddfbf224b6a0ee3711e2b42a15b887e7f5e7 Mon Sep 17 00:00:00 2001 From: tyranron <tyranron@gmail.com> Date: Wed, 8 Jun 2022 11:06:28 +0200 Subject: [PATCH] Restore old reflection impls --- juniper/src/macros/reflect.rs | 122 +++++++++++++++++++++- juniper/src/types/nullable.rs | 6 +- juniper/src/types/scalars.rs | 13 +++ juniper_codegen/src/graphql_scalar/mod.rs | 59 +++++++++-- 4 files changed, 187 insertions(+), 13 deletions(-) diff --git a/juniper/src/macros/reflect.rs b/juniper/src/macros/reflect.rs index b24ba4f5..e67762df 100644 --- a/juniper/src/macros/reflect.rs +++ b/juniper/src/macros/reflect.rs @@ -7,7 +7,7 @@ use crate::{ can_be_subtype, fnv1a128, str_eq, str_exists_in_arr, type_len_with_wrapped_val, wrap, Argument, Arguments, FieldName, Name, Names, Type, Types, WrappedValue, }, - Arguments as FieldArguments, ExecutionResult, Executor, GraphQLValue, ScalarValue, + Arguments as FieldArguments, ExecutionResult, Executor, GraphQLValue, ScalarValue, Nullable, }; /// Naming of a [GraphQL object][1], [scalar][2] or [interface][3] [`Type`]. @@ -31,6 +31,10 @@ pub trait BaseType<S> { const NAME: Type; } +impl<'a, S, T: BaseType<S> + ?Sized> BaseType<S> for &'a T { + const NAME: Type = T::NAME; +} + impl<'ctx, S, T> BaseType<S> for (&'ctx T::Context, T) where S: ScalarValue, @@ -39,6 +43,42 @@ where const NAME: Type = T::NAME; } +impl<S, T: BaseType<S>> BaseType<S> for Option<T> { + const NAME: Type = T::NAME; +} + +impl<S, T: BaseType<S>> BaseType<S> for Nullable<T> { + const NAME: Type = T::NAME; +} + +impl<S, T: BaseType<S>, E> BaseType<S> for Result<T, E> { + const NAME: Type = T::NAME; +} + +impl<S, T: BaseType<S>> BaseType<S> for Vec<T> { + const NAME: Type = T::NAME; +} + +impl<S, T: BaseType<S>> BaseType<S> for [T] { + const NAME: Type = T::NAME; +} + +impl<S, T: BaseType<S>, const N: usize> BaseType<S> for [T; N] { + const NAME: Type = T::NAME; +} + +impl<S, T: BaseType<S> + ?Sized> BaseType<S> for Box<T> { + const NAME: Type = T::NAME; +} + +impl<S, T: BaseType<S> + ?Sized> BaseType<S> for Arc<T> { + const NAME: Type = T::NAME; +} + +impl<S, T: BaseType<S> + ?Sized> BaseType<S> for Rc<T> { + const NAME: Type = T::NAME; +} + /// [Sub-types][2] of a [GraphQL object][1]. /// /// This trait is transparent to [`Option`], [`Vec`] and other containers. @@ -52,6 +92,10 @@ pub trait BaseSubTypes<S> { const NAMES: Types; } +impl<'a, S, T: BaseSubTypes<S> + ?Sized> BaseSubTypes<S> for &'a T { + const NAMES: Types = T::NAMES; +} + impl<'ctx, S, T> BaseSubTypes<S> for (&'ctx T::Context, T) where S: ScalarValue, @@ -60,6 +104,42 @@ where const NAMES: Types = T::NAMES; } +impl<S, T: BaseSubTypes<S>> BaseSubTypes<S> for Option<T> { + const NAMES: Types = T::NAMES; +} + +impl<S, T: BaseSubTypes<S>> BaseSubTypes<S> for Nullable<T> { + const NAMES: Types = T::NAMES; +} + +impl<S, T: BaseSubTypes<S>, E> BaseSubTypes<S> for Result<T, E> { + const NAMES: Types = T::NAMES; +} + +impl<S, T: BaseSubTypes<S>> BaseSubTypes<S> for Vec<T> { + const NAMES: Types = T::NAMES; +} + +impl<S, T: BaseSubTypes<S>> BaseSubTypes<S> for [T] { + const NAMES: Types = T::NAMES; +} + +impl<S, T: BaseSubTypes<S>, const N: usize> BaseSubTypes<S> for [T; N] { + const NAMES: Types = T::NAMES; +} + +impl<S, T: BaseSubTypes<S> + ?Sized> BaseSubTypes<S> for Box<T> { + const NAMES: Types = T::NAMES; +} + +impl<S, T: BaseSubTypes<S> + ?Sized> BaseSubTypes<S> for Arc<T> { + const NAMES: Types = T::NAMES; +} + +impl<S, T: BaseSubTypes<S> + ?Sized> BaseSubTypes<S> for Rc<T> { + const NAMES: Types = T::NAMES; +} + // TODO: Just use `&str`s once they're allowed in `const` generics. /// Encoding of a composed GraphQL type in numbers. /// @@ -117,6 +197,46 @@ where const VALUE: u128 = T::VALUE; } +impl<S, T: WrappedType<S>> WrappedType<S> for Option<T> { + const VALUE: u128 = T::VALUE * 10 + 2; +} + +impl<S, T: WrappedType<S>> WrappedType<S> for Nullable<T> { + const VALUE: u128 = T::VALUE * 10 + 2; +} + +impl<S, T: WrappedType<S>, E> WrappedType<S> for Result<T, E> { + const VALUE: u128 = T::VALUE; +} + +impl<S, T: WrappedType<S>> WrappedType<S> for Vec<T> { + const VALUE: u128 = T::VALUE * 10 + 3; +} + +impl<S, T: WrappedType<S>> WrappedType<S> for [T] { + const VALUE: u128 = T::VALUE * 10 + 3; +} + +impl<S, T: WrappedType<S>, const N: usize> WrappedType<S> for [T; N] { + const VALUE: u128 = T::VALUE * 10 + 3; +} + +impl<'a, S, T: WrappedType<S> + ?Sized> WrappedType<S> for &'a T { + const VALUE: u128 = T::VALUE; +} + +impl<S, T: WrappedType<S> + ?Sized> WrappedType<S> for Box<T> { + const VALUE: u128 = T::VALUE; +} + +impl<S, T: WrappedType<S> + ?Sized> WrappedType<S> for Arc<T> { + const VALUE: u128 = T::VALUE; +} + +impl<S, T: WrappedType<S> + ?Sized> WrappedType<S> for Rc<T> { + const VALUE: u128 = T::VALUE; +} + /// [GraphQL object][1] or [interface][2] [field arguments][3] [`Names`]. /// /// [1]: https://spec.graphql.org/October2021#sec-Objects diff --git a/juniper/src/types/nullable.rs b/juniper/src/types/nullable.rs index 04165f3b..daec6044 100644 --- a/juniper/src/types/nullable.rs +++ b/juniper/src/types/nullable.rs @@ -244,7 +244,7 @@ impl<T: Copy> Nullable<&T> { /// Maps this `Nullable<&T>` to a `Nullable<T>` by [`Copy`]ing the contents /// of this [`Nullable`]. pub fn copied(self) -> Nullable<T> { - self.map(|&t| t) + self.map(|t| *t) } } @@ -252,7 +252,7 @@ impl<T: Copy> Nullable<&mut T> { /// Maps this `Nullable<&mut T>` to a `Nullable<T>` by [`Copy`]ing the /// contents of this [`Nullable`]. pub fn copied(self) -> Nullable<T> { - self.map(|&mut t| t) + self.map(|t| *t) } } @@ -260,7 +260,7 @@ impl<T: Clone> Nullable<&T> { /// Maps this `Nullable<&T>` to a `Nullable<T>` by [`Clone`]ing the contents /// of this [`Nullable`]. pub fn cloned(self) -> Nullable<T> { - self.map(|t| t.clone()) + self.map(T::clone) } } diff --git a/juniper/src/types/scalars.rs b/juniper/src/types/scalars.rs index 0f8bb408..66e26e74 100644 --- a/juniper/src/types/scalars.rs +++ b/juniper/src/types/scalars.rs @@ -8,6 +8,7 @@ use crate::{ ast::{InputValue, Selection, ToInputValue}, executor::{ExecutionResult, Executor, Registry}, graphql_scalar, + macros::reflect, parser::{LexerError, ParseError, ScalarToken, Token}, schema::meta::MetaType, types::{ @@ -195,6 +196,18 @@ 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_codegen/src/graphql_scalar/mod.rs b/juniper_codegen/src/graphql_scalar/mod.rs index 9e6e49cf..5a706851 100644 --- a/juniper_codegen/src/graphql_scalar/mod.rs +++ b/juniper_codegen/src/graphql_scalar/mod.rs @@ -329,17 +329,19 @@ 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().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_and_output_type().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_output_type().to_tokens(into); + //self.impl_graphql_output_type().to_tokens(into); //self.impl_graphql_scalar().to_tokens(into); - self.impl_reflect().to_tokens(into); + //self.impl_reflect().to_tokens(into); } } @@ -850,6 +852,45 @@ impl Definition { } } + /// Returns generated code implementing [`BaseType`], [`BaseSubTypes`] and + /// [`WrappedType`] traits for this [GraphQL scalar][1]. + /// + /// [`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); + let (impl_gens, _, where_clause) = generics.split_for_impl(); + + quote! { + #[automatically_derived] + impl#impl_gens ::juniper::macros::reflect::BaseType<#scalar> for #ty + #where_clause + { + const NAME: ::juniper::macros::reflect::Type = #name; + } + + #[automatically_derived] + impl#impl_gens ::juniper::macros::reflect::BaseSubTypes<#scalar> for #ty + #where_clause + { + const NAMES: ::juniper::macros::reflect::Types = + &[<Self as ::juniper::macros::reflect::BaseType<#scalar>>::NAME]; + } + + #[automatically_derived] + impl#impl_gens ::juniper::macros::reflect::WrappedType<#scalar> for #ty + #where_clause + { + const VALUE: ::juniper::macros::reflect::WrappedValue = 1; + } + } + } + /// Returns generated code implementing [`reflect::BaseType`], /// [`reflect::BaseSubTypes`] and [`reflect::WrappedType`] traits for this /// [GraphQL scalar][0].