From 22f3f1887ea8f0e93c0a3f49768a7af751274e79 Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 31 May 2022 00:29:14 +0200 Subject: [PATCH] Bikeshed reflection, vol.1 --- juniper/src/macros/reflect.rs | 126 ++-------------------- juniper/src/types/arc.rs | 25 ++++- juniper/src/types/array.rs | 23 +++- juniper/src/types/box.rs | 25 ++++- juniper/src/types/mod.rs | 1 + juniper/src/types/nullable.rs | 25 ++++- juniper/src/types/option.rs | 23 +++- juniper/src/types/rc.rs | 25 ++++- juniper/src/types/ref.rs | 25 ++++- juniper/src/types/ref_mut.rs | 23 +++- juniper/src/types/result.rs | 24 +++++ juniper/src/types/slice.rs | 23 +++- juniper/src/types/str.rs | 6 +- juniper/src/types/vec.rs | 23 +++- juniper_codegen/src/graphql_scalar/mod.rs | 7 +- 15 files changed, 267 insertions(+), 137 deletions(-) create mode 100644 juniper/src/types/result.rs diff --git a/juniper/src/macros/reflect.rs b/juniper/src/macros/reflect.rs index 4cba097f..912a2524 100644 --- a/juniper/src/macros/reflect.rs +++ b/juniper/src/macros/reflect.rs @@ -44,10 +44,6 @@ pub trait BaseType { const NAME: Type; } -impl<'a, S, T: BaseType + ?Sized> BaseType for &'a T { - const NAME: Type = T::NAME; -} - impl<'ctx, S, T> BaseType for (&'ctx T::Context, T) where S: ScalarValue, @@ -56,42 +52,6 @@ where const NAME: Type = T::NAME; } -impl> BaseType for Option { - const NAME: Type = T::NAME; -} - -impl> BaseType for Nullable { - const NAME: Type = T::NAME; -} - -impl, E> BaseType for Result { - const NAME: Type = T::NAME; -} - -impl> BaseType for Vec { - const NAME: Type = T::NAME; -} - -impl> BaseType for [T] { - const NAME: Type = T::NAME; -} - -impl, const N: usize> BaseType for [T; N] { - const NAME: Type = T::NAME; -} - -impl + ?Sized> BaseType for Box { - const NAME: Type = T::NAME; -} - -impl + ?Sized> BaseType for Arc { - const NAME: Type = T::NAME; -} - -impl + ?Sized> BaseType for Rc { - const NAME: Type = T::NAME; -} - /// [Sub-types][2] of a [GraphQL object][1]. /// /// This trait is transparent to [`Option`], [`Vec`] and other containers. @@ -105,10 +65,6 @@ pub trait BaseSubTypes { const NAMES: Types; } -impl<'a, S, T: BaseSubTypes + ?Sized> BaseSubTypes for &'a T { - const NAMES: Types = T::NAMES; -} - impl<'ctx, S, T> BaseSubTypes for (&'ctx T::Context, T) where S: ScalarValue, @@ -117,42 +73,6 @@ where const NAMES: Types = T::NAMES; } -impl> BaseSubTypes for Option { - const NAMES: Types = T::NAMES; -} - -impl> BaseSubTypes for Nullable { - const NAMES: Types = T::NAMES; -} - -impl, E> BaseSubTypes for Result { - const NAMES: Types = T::NAMES; -} - -impl> BaseSubTypes for Vec { - const NAMES: Types = T::NAMES; -} - -impl> BaseSubTypes for [T] { - const NAMES: Types = T::NAMES; -} - -impl, const N: usize> BaseSubTypes for [T; N] { - const NAMES: Types = T::NAMES; -} - -impl + ?Sized> BaseSubTypes for Box { - const NAMES: Types = T::NAMES; -} - -impl + ?Sized> BaseSubTypes for Arc { - const NAMES: Types = T::NAMES; -} - -impl + ?Sized> BaseSubTypes for Rc { - const NAMES: Types = T::NAMES; -} - /// Alias for a value of a [`WrappedType`] (composed GraphQL type). pub type WrappedValue = u128; @@ -163,7 +83,7 @@ pub type WrappedValue = u128; /// because of the [wrapping types][2]. To work around this we use a /// [`WrappedValue`] which is represented via [`u128`] number in the following /// encoding: -/// - In base case of non-nullable [object][1] [`VALUE`] is `1`. +/// - In base case of non-nullable singular [object][1] [`VALUE`] is `1`. /// - To represent nullability we "append" `2` to the [`VALUE`], so /// [`Option`]`<`[object][1]`>` has [`VALUE`] of `12`. /// - To represent list we "append" `3` to the [`VALUE`], so @@ -213,44 +133,18 @@ where const VALUE: u128 = T::VALUE; } -impl> WrappedType for Option { - const VALUE: u128 = T::VALUE * 10 + 2; -} +pub mod wrap { + use super::WrappedValue; -impl> WrappedType for Nullable { - const VALUE: u128 = T::VALUE * 10 + 2; -} + pub const SINGULAR: WrappedValue = 1; -impl, E> WrappedType for Result { - const VALUE: u128 = T::VALUE; -} + pub const fn nullable(val: WrappedValue) -> WrappedValue { + val * 10 + 2 + } -impl> WrappedType for Vec { - const VALUE: u128 = T::VALUE * 10 + 3; -} - -impl> WrappedType for [T] { - const VALUE: u128 = T::VALUE * 10 + 3; -} - -impl, const N: usize> WrappedType for [T; N] { - const VALUE: u128 = T::VALUE * 10 + 3; -} - -impl<'a, S, T: WrappedType + ?Sized> WrappedType for &'a T { - const VALUE: u128 = T::VALUE; -} - -impl + ?Sized> WrappedType for Box { - const VALUE: u128 = T::VALUE; -} - -impl + ?Sized> WrappedType for Arc { - const VALUE: u128 = T::VALUE; -} - -impl + ?Sized> WrappedType for Rc { - const VALUE: u128 = T::VALUE; + pub const fn list(val: WrappedValue) -> WrappedValue { + val * 10 + 3 + } } /// Alias for a [GraphQL object][1] or [interface][2] [field argument][3] name. diff --git a/juniper/src/types/arc.rs b/juniper/src/types/arc.rs index 6c9b8faf..33804c3f 100644 --- a/juniper/src/types/arc.rs +++ b/juniper/src/types/arc.rs @@ -6,8 +6,8 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, - Registry, Selection, + reflect, resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, + IntoFieldError, Registry, Selection, }; impl resolve::Type for Arc @@ -247,3 +247,24 @@ where T::assert_union() } } + +impl reflect::BaseType for Arc +where + T: reflect::BaseType + ?Sized, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for Arc +where + T: reflect::BaseSubTypes + ?Sized, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for Arc +where + T: reflect::WrappedType + ?Sized, +{ + const VALUE: reflect::WrappedValue = T::VALUE; +} diff --git a/juniper/src/types/array.rs b/juniper/src/types/array.rs index e018148d..4cd5856b 100644 --- a/juniper/src/types/array.rs +++ b/juniper/src/types/array.rs @@ -4,7 +4,7 @@ use crate::{ executor::{ExecutionResult, Executor, Registry}, - graphql, resolve, + graphql, reflect, resolve, schema::meta::MetaType, BoxFuture, Selection, }; @@ -81,3 +81,24 @@ where T::assert_output_type() } } + +impl reflect::BaseType for [T; N] +where + T: reflect::BaseType, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for [T; N] +where + T: reflect::BaseSubTypes, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for [T; N] +where + T: reflect::WrappedType, +{ + const VALUE: reflect::WrappedValue = reflect::wrap::list(T::VALUE); +} diff --git a/juniper/src/types/box.rs b/juniper/src/types/box.rs index 337d1540..1237ed6e 100644 --- a/juniper/src/types/box.rs +++ b/juniper/src/types/box.rs @@ -4,8 +4,8 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, - Registry, Selection, + reflect, resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, + IntoFieldError, Registry, Selection, }; impl resolve::Type for Box @@ -245,3 +245,24 @@ where T::assert_union() } } + +impl reflect::BaseType for Box +where + T: reflect::BaseType + ?Sized, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for Box +where + T: reflect::BaseSubTypes + ?Sized, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for Box +where + T: reflect::WrappedType + ?Sized, +{ + const VALUE: reflect::WrappedValue = T::VALUE; +} diff --git a/juniper/src/types/mod.rs b/juniper/src/types/mod.rs index 58dfde7c..5e529d61 100644 --- a/juniper/src/types/mod.rs +++ b/juniper/src/types/mod.rs @@ -7,6 +7,7 @@ mod option; pub mod rc; pub mod r#ref; mod ref_mut; +mod result; mod slice; mod r#str; mod vec; diff --git a/juniper/src/types/nullable.rs b/juniper/src/types/nullable.rs index eb1ee10c..4113ea81 100644 --- a/juniper/src/types/nullable.rs +++ b/juniper/src/types/nullable.rs @@ -7,7 +7,7 @@ use futures::future; use crate::{ ast::{FromInputValue, InputValue, ToInputValue}, executor::{ExecutionResult, Executor, Registry}, - graphql, resolve, + graphql, reflect, resolve, schema::meta::MetaType, types::{ async_await::GraphQLValueAsync, @@ -361,6 +361,29 @@ where } } +impl reflect::BaseType for Nullable +where + T: reflect::BaseType, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for Nullable +where + T: reflect::BaseSubTypes, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for Nullable +where + T: reflect::WrappedType, +{ + const VALUE: reflect::WrappedValue = reflect::wrap::nullable(T::VALUE); +} + +//////////////////////////////////////////////////////////////////////////////// + impl GraphQLType for Nullable where T: GraphQLType, diff --git a/juniper/src/types/option.rs b/juniper/src/types/option.rs index ec3f0649..75320f82 100644 --- a/juniper/src/types/option.rs +++ b/juniper/src/types/option.rs @@ -4,7 +4,7 @@ use futures::future; use crate::{ executor::{ExecutionResult, Executor, Registry}, - graphql, resolve, + graphql, reflect, resolve, schema::meta::MetaType, BoxFuture, Selection, }; @@ -93,3 +93,24 @@ where T::assert_output_type() } } + +impl reflect::BaseType for Option +where + T: reflect::BaseType, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for Option +where + T: reflect::BaseSubTypes, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for Option +where + T: reflect::WrappedType, +{ + const VALUE: reflect::WrappedValue = reflect::wrap::nullable(T::VALUE); +} diff --git a/juniper/src/types/rc.rs b/juniper/src/types/rc.rs index 8bae3053..515290b1 100644 --- a/juniper/src/types/rc.rs +++ b/juniper/src/types/rc.rs @@ -6,8 +6,8 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, - Registry, Selection, + reflect, resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, + IntoFieldError, Registry, Selection, }; impl resolve::Type for Rc @@ -247,3 +247,24 @@ where T::assert_union() } } + +impl reflect::BaseType for Rc +where + T: reflect::BaseType + ?Sized, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for Rc +where + T: reflect::BaseSubTypes + ?Sized, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for Rc +where + T: reflect::WrappedType + ?Sized, +{ + const VALUE: reflect::WrappedValue = T::VALUE; +} diff --git a/juniper/src/types/ref.rs b/juniper/src/types/ref.rs index 83d33ac1..646b4566 100644 --- a/juniper/src/types/ref.rs +++ b/juniper/src/types/ref.rs @@ -6,8 +6,8 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, - Registry, Selection, + reflect, resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, + IntoFieldError, Registry, Selection, }; impl<'me, T, Info, S> resolve::Type for &'me T @@ -233,3 +233,24 @@ where T::assert_union() } } + +impl<'me, T, S> reflect::BaseType for &'me T +where + T: reflect::BaseType + ?Sized, +{ + const NAME: reflect::Type = T::NAME; +} + +impl<'me, T, S> reflect::BaseSubTypes for &'me T +where + T: reflect::BaseSubTypes + ?Sized, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl<'me, T, S> reflect::WrappedType for &'me T +where + T: reflect::WrappedType + ?Sized, +{ + const VALUE: reflect::WrappedValue = T::VALUE; +} diff --git a/juniper/src/types/ref_mut.rs b/juniper/src/types/ref_mut.rs index a9418a0f..36a576d7 100644 --- a/juniper/src/types/ref_mut.rs +++ b/juniper/src/types/ref_mut.rs @@ -6,7 +6,7 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection, + reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection, }; impl<'me, T, Info, S> resolve::Type for &'me mut T @@ -204,3 +204,24 @@ where T::assert_union() } } + +impl<'me, T, S> reflect::BaseType for &'me mut T +where + T: reflect::BaseType + ?Sized, +{ + const NAME: reflect::Type = T::NAME; +} + +impl<'me, T, S> reflect::BaseSubTypes for &'me mut T +where + T: reflect::BaseSubTypes + ?Sized, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl<'me, T, S> reflect::WrappedType for &'me mut T +where + T: reflect::WrappedType + ?Sized, +{ + const VALUE: reflect::WrappedValue = T::VALUE; +} diff --git a/juniper/src/types/result.rs b/juniper/src/types/result.rs new file mode 100644 index 00000000..1077f979 --- /dev/null +++ b/juniper/src/types/result.rs @@ -0,0 +1,24 @@ +//! GraphQL implementation for [`Result`]. + +use crate::reflect; + +impl reflect::BaseType for Result +where + T: reflect::BaseType, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for Result +where + T: reflect::BaseSubTypes, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for Result +where + T: reflect::WrappedType, +{ + const VALUE: reflect::WrappedValue = T::VALUE; +} diff --git a/juniper/src/types/slice.rs b/juniper/src/types/slice.rs index e3ad5b49..5a5b6b52 100644 --- a/juniper/src/types/slice.rs +++ b/juniper/src/types/slice.rs @@ -4,7 +4,7 @@ use crate::{ executor::{ExecutionResult, Executor, Registry}, - graphql, resolve, + graphql, reflect, resolve, schema::meta::MetaType, BoxFuture, Selection, }; @@ -79,3 +79,24 @@ where T::assert_output_type() } } + +impl reflect::BaseType for [T] +where + T: reflect::BaseType, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for [T] +where + T: reflect::BaseSubTypes, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for [T] +where + T: reflect::WrappedType, +{ + const VALUE: reflect::WrappedValue = reflect::wrap::list(T::VALUE); +} diff --git a/juniper/src/types/str.rs b/juniper/src/types/str.rs index 24861e6b..b8f26985 100644 --- a/juniper/src/types/str.rs +++ b/juniper/src/types/str.rs @@ -7,10 +7,10 @@ use std::{rc::Rc, sync::Arc}; use futures::future; use crate::{ - graphql, reflect, + graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, BoxFuture, ExecutionResult, Executor, Registry, ScalarValue, Selection, + reflect, resolve, BoxFuture, ExecutionResult, Executor, Registry, ScalarValue, Selection, }; impl resolve::Type for str { @@ -129,5 +129,5 @@ impl reflect::BaseSubTypes for str { } impl reflect::WrappedType for str { - const VALUE: reflect::WrappedValue = 1; + const VALUE: reflect::WrappedValue = reflect::wrap::SINGULAR; } diff --git a/juniper/src/types/vec.rs b/juniper/src/types/vec.rs index a085f90f..8a96f5ad 100644 --- a/juniper/src/types/vec.rs +++ b/juniper/src/types/vec.rs @@ -2,7 +2,7 @@ use crate::{ executor::{ExecutionResult, Executor, Registry}, - graphql, resolve, + graphql, reflect, resolve, schema::meta::MetaType, BoxFuture, Selection, }; @@ -77,3 +77,24 @@ where T::assert_output_type() } } + +impl reflect::BaseType for Vec +where + T: reflect::BaseType, +{ + const NAME: reflect::Type = T::NAME; +} + +impl reflect::BaseSubTypes for Vec +where + T: reflect::BaseSubTypes, +{ + const NAMES: reflect::Types = T::NAMES; +} + +impl reflect::WrappedType for Vec +where + T: reflect::WrappedType, +{ + const VALUE: reflect::WrappedValue = reflect::wrap::list(T::VALUE); +} diff --git a/juniper_codegen/src/graphql_scalar/mod.rs b/juniper_codegen/src/graphql_scalar/mod.rs index 7e98eae3..d094b3d1 100644 --- a/juniper_codegen/src/graphql_scalar/mod.rs +++ b/juniper_codegen/src/graphql_scalar/mod.rs @@ -471,15 +471,13 @@ impl Definition { let (info, generics) = self.mix_info(generics); let (impl_gens, _, where_clause) = generics.split_for_impl(); - let name = &self.name; - quote! { #[automatically_derived] impl#impl_gens ::juniper::resolve::TypeName<#info> for #ty #where_clause { fn type_name(_: &#info) -> &'static str { - #name + >::NAME } } } @@ -783,7 +781,8 @@ impl Definition { impl#impl_gens ::juniper::reflect::WrappedType<#scalar> for #ty #where_clause { - const VALUE: ::juniper::reflect::WrappedValue = 1; + const VALUE: ::juniper::reflect::WrappedValue = + ::juniper::reflect::wrap::SINGULAR; } } }