From 2d1e5d38b753859401ad634fddc0ecd75ad3da21 Mon Sep 17 00:00:00 2001 From: tyranron <tyranron@gmail.com> Date: Fri, 22 Apr 2022 16:48:19 +0300 Subject: [PATCH] Impl some basic types --- juniper/src/executor/mod.rs | 63 +++++++++ juniper/src/graphql/mod.rs | 55 ++++++++ juniper/src/graphql/resolve.rs | 248 ++++++++++++++++++++++++++------- juniper/src/lib.rs | 2 +- juniper/src/resolve/mod.rs | 67 +++++++-- juniper/src/types/arc.rs | 186 +++++++++++++++++++++++++ juniper/src/types/box.rs | 184 ++++++++++++++++++++++++ juniper/src/types/iter.rs | 65 +++++++++ juniper/src/types/mod.rs | 9 ++ juniper/src/types/option.rs | 78 +++++++++++ juniper/src/types/rc.rs | 186 +++++++++++++++++++++++++ juniper/src/types/ref.rs | 182 ++++++++++++++++++++++++ juniper/src/types/ref_mut.rs | 182 ++++++++++++++++++++++++ juniper/src/types/vec.rs | 77 ++++++++++ 14 files changed, 1523 insertions(+), 61 deletions(-) create mode 100644 juniper/src/types/arc.rs create mode 100644 juniper/src/types/box.rs create mode 100644 juniper/src/types/iter.rs create mode 100644 juniper/src/types/option.rs create mode 100644 juniper/src/types/rc.rs create mode 100644 juniper/src/types/ref.rs create mode 100644 juniper/src/types/ref_mut.rs create mode 100644 juniper/src/types/vec.rs diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index cf35af15..23073222 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -17,6 +17,7 @@ use crate::{ Selection, ToInputValue, Type, }, parser::{SourcePosition, Spanning}, + resolve, schema::{ meta::{ Argument, DeprecationStatus, EnumMeta, EnumValue, Field, InputObjectMeta, @@ -83,6 +84,12 @@ where field_path: Arc<FieldPath<'a>>, } +impl<'r, 'a, Ctx: ?Sized, S> Executor<'r, 'a, Ctx, S> { + pub(crate) fn current_type_new(&self) -> &TypeType<'a, S> { + &self.current_type + } +} + /// Error type for errors that occur during query execution /// /// All execution errors contain the source position in the query of the field @@ -1183,6 +1190,32 @@ impl<'r, S: 'r> Registry<'r, S> { } } + /// Returns a [`Type`] meta information for the specified [`graphql::Type`], + /// registered in this [`Registry`]. + /// + /// If this [`Registry`] doesn't contain a [`Type`] meta information with + /// such [`TypeName`] before, it will construct the one and store it. + /// + /// [`graphql::Type`]: resolve::Type + /// [`TypeName`]: resolve::TypeName + pub fn get_type_new<T, Info>(&mut self, info: &Info) -> Type<'r> + where + T: resolve::Type<Info, S> + resolve::TypeName<Info> + ?Sized, + Info: ?Sized, + { + let name = T::type_name(info); + let validated_name = name.parse::<Name>().unwrap(); + if !self.types.contains_key(name) { + self.insert_placeholder( + validated_name.clone(), + Type::NonNullNamed(Cow::Owned(name.to_string())), + ); + let meta = T::meta(self, info); + self.types.insert(validated_name, meta); + } + self.types[name].as_type() + } + /// Creates a [`Field`] with the provided `name`. pub fn field<T>(&mut self, name: &str, info: &T::TypeInfo) -> Field<'r, S> where @@ -1278,6 +1311,24 @@ impl<'r, S: 'r> Registry<'r, S> { ListMeta::new(of_type, expected_size) } + /// Builds a [`ListMeta`] information for the specified [`graphql::Type`]. + /// + /// Specifying `expected_size` will be used in validation to ensure that + /// values of this type matches it. + /// + /// [`graphql::Type`]: resolve::Type + pub fn build_list_type_new<T, Info>( + &mut self, + info: &Info, + expected_size: Option<usize>, + ) -> ListMeta<'r> + where + T: resolve::Type<Info, S> + ?Sized, + Info: ?Sized, + { + ListMeta::new(T::meta(self, info).as_type(), expected_size) + } + /// Creates a [`NullableMeta`] type. pub fn build_nullable_type<T>(&mut self, info: &T::TypeInfo) -> NullableMeta<'r> where @@ -1288,6 +1339,18 @@ impl<'r, S: 'r> Registry<'r, S> { NullableMeta::new(of_type) } + /// Builds a [`NullableMeta`] information for the specified + /// [`graphql::Type`]. + /// + /// [`graphql::Type`]: resolve::Type + pub fn build_nullable_type_new<T, Info>(&mut self, info: &Info) -> NullableMeta<'r> + where + T: resolve::Type<Info, S> + ?Sized, + Info: ?Sized, + { + NullableMeta::new(T::meta(self, info).as_type()) + } + /// Creates an [`ObjectMeta`] type with the given `fields`. pub fn build_object_type<T>( &mut self, diff --git a/juniper/src/graphql/mod.rs b/juniper/src/graphql/mod.rs index 581d1dcd..4d87480d 100644 --- a/juniper/src/graphql/mod.rs +++ b/juniper/src/graphql/mod.rs @@ -1 +1,56 @@ pub mod resolve; + +use crate::DefaultScalarValue; + +pub use crate::value::Value; + +pub use self::resolve::Type; + +pub trait Interface<S = DefaultScalarValue>: + OutputType<S> + + Type<S> + + resolve::TypeName + + resolve::ConcreteTypeName + + resolve::Value<S> + + resolve::ValueAsync<S> + + resolve::ConcreteValue<S> + + resolve::ConcreteValueAsync<S> + + resolve::Field<S> + + resolve::FieldAsync<S> +{ + fn assert_interface(); +} + +pub trait Object<S = DefaultScalarValue>: + OutputType<S> + + Type<S> + + resolve::TypeName + + resolve::ConcreteTypeName + + resolve::Value<S> + + resolve::ValueAsync<S> + + resolve::Field<S> + + resolve::FieldAsync<S> +{ + fn assert_object(); +} + +pub trait Union<S = DefaultScalarValue>: + OutputType<S> + + Type<S> + + resolve::TypeName + + resolve::ConcreteTypeName + + resolve::Value<S> + + resolve::ValueAsync<S> + + resolve::ConcreteValue<S> + + resolve::ConcreteValueAsync<S> +{ + fn assert_union(); +} + +pub trait InputType<S = DefaultScalarValue> { + fn assert_input_type(); +} + +pub trait OutputType<S = DefaultScalarValue> { + fn assert_output_type(); +} diff --git a/juniper/src/graphql/resolve.rs b/juniper/src/graphql/resolve.rs index 068115a8..22fe5342 100644 --- a/juniper/src/graphql/resolve.rs +++ b/juniper/src/graphql/resolve.rs @@ -1,10 +1,25 @@ use crate::{ - executor::{ExecutionResult, Executor, Registry}, - resolve, - schema::meta::MetaType, - Arguments, DefaultScalarValue, + meta::MetaType, resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, + Registry, Selection, }; +pub trait Type<S = DefaultScalarValue> { + fn meta<'r, Info: ?Sized>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + Self: resolve::Type<Info, S>; +} + +impl<T: ?Sized, S> Type<S> for T { + fn meta<'r, Info: ?Sized>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + Self: resolve::Type<Info, S>, + { + <Self as resolve::Type<Info, S>>::meta(registry, info) + } +} + pub trait TypeName { fn type_name<Info: ?Sized>(info: &Info) -> &str where @@ -20,52 +35,6 @@ impl<T: ?Sized> TypeName for T { } } -pub trait Type<S = DefaultScalarValue> { - fn meta<'r, Info: ?Sized>(info: &Info, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - Self: resolve::Type<Info, S>; -} - -impl<T: ?Sized, S> Type<S> for T { - fn meta<'r, Info: ?Sized>(info: &Info, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r, - Self: resolve::Type<Info, S>, - { - <Self as resolve::Type<Info, S>>::meta(info, registry) - } -} - -pub trait Field<S = DefaultScalarValue> { - fn resolve_field<Info: ?Sized, Ctx: ?Sized>( - &self, - info: &Info, - field_name: &str, - arguments: &Arguments<S>, - executor: &Executor<Ctx, S>, - ) -> ExecutionResult<S> - where - Self: resolve::Field<Info, Ctx, S>; -} - -impl<T: ?Sized, S> Field<S> for T { - fn resolve_field<Info: ?Sized, Ctx: ?Sized>( - &self, - info: &Info, - field_name: &str, - arguments: &Arguments<S>, - executor: &Executor<Ctx, S>, - ) -> ExecutionResult<S> - where - Self: resolve::Field<Info, Ctx, S>, - { - <Self as resolve::Field<Info, Ctx, S>>::resolve_field( - self, info, field_name, arguments, executor, - ) - } -} - pub trait ConcreteTypeName { fn concrete_type_name<'i, Info: ?Sized>(&self, info: &'i Info) -> &'i str where @@ -80,3 +49,182 @@ impl<T: ?Sized> ConcreteTypeName for T { <Self as resolve::ConcreteTypeName<Info>>::concrete_type_name(self, info) } } + +pub trait Value<S = DefaultScalarValue> { + fn resolve_value<Info: ?Sized, Ctx: ?Sized>( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> + where + Self: resolve::Value<Info, Ctx, S>; +} + +impl<T: ?Sized, S> Value<S> for T { + fn resolve_value<Info: ?Sized, Ctx: ?Sized>( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> + where + Self: resolve::Value<Info, Ctx, S>, + { + <Self as resolve::Value<Info, Ctx, S>>::resolve_value(self, selection_set, info, executor) + } +} + +pub trait ValueAsync<S = DefaultScalarValue> { + fn resolve_value_async<'r, Info: ?Sized, Ctx: ?Sized>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> + where + Self: resolve::ValueAsync<Info, Ctx, S>; +} + +impl<T: ?Sized, S> ValueAsync<S> for T { + fn resolve_value_async<'r, Info: ?Sized, Ctx: ?Sized>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> + where + Self: resolve::ValueAsync<Info, Ctx, S>, + { + <Self as resolve::ValueAsync<Info, Ctx, S>>::resolve_value_async( + self, + selection_set, + info, + executor, + ) + } +} + +pub trait ConcreteValue<S = DefaultScalarValue> { + fn resolve_concrete_value<Info: ?Sized, Ctx: ?Sized>( + &self, + type_name: &str, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> + where + Self: resolve::ConcreteValue<Info, Ctx, S>; +} + +impl<T: ?Sized, S> ConcreteValue<S> for T { + fn resolve_concrete_value<Info: ?Sized, Ctx: ?Sized>( + &self, + type_name: &str, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> + where + Self: resolve::ConcreteValue<Info, Ctx, S>, + { + <Self as resolve::ConcreteValue<Info, Ctx, S>>::resolve_concrete_value( + self, + type_name, + selection_set, + info, + executor, + ) + } +} + +pub trait ConcreteValueAsync<S = DefaultScalarValue> { + fn resolve_concrete_value_async<'r, Info: ?Sized, Ctx: ?Sized>( + &'r self, + type_name: &str, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> + where + Self: resolve::ConcreteValueAsync<Info, Ctx, S>; +} + +impl<T: ?Sized, S> ConcreteValueAsync<S> for T { + fn resolve_concrete_value_async<'r, Info: ?Sized, Ctx: ?Sized>( + &'r self, + type_name: &str, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> + where + Self: resolve::ConcreteValueAsync<Info, Ctx, S>, + { + <Self as resolve::ConcreteValueAsync<Info, Ctx, S>>::resolve_concrete_value_async( + self, + type_name, + selection_set, + info, + executor, + ) + } +} + +pub trait Field<S = DefaultScalarValue> { + fn resolve_field<Info: ?Sized, Ctx: ?Sized>( + &self, + field_name: &str, + arguments: &Arguments<S>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> + where + Self: resolve::Field<Info, Ctx, S>; +} + +impl<T: ?Sized, S> Field<S> for T { + fn resolve_field<Info: ?Sized, Ctx: ?Sized>( + &self, + field_name: &str, + arguments: &Arguments<S>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> + where + Self: resolve::Field<Info, Ctx, S>, + { + <Self as resolve::Field<Info, Ctx, S>>::resolve_field( + self, field_name, arguments, info, executor, + ) + } +} + +pub trait FieldAsync<S = DefaultScalarValue> { + fn resolve_field_async<'r, Info: ?Sized, Ctx: ?Sized>( + &'r self, + field_name: &'r str, + arguments: &'r Arguments<S>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> + where + Self: resolve::FieldAsync<Info, Ctx, S>; +} + +impl<T: ?Sized, S> FieldAsync<S> for T { + fn resolve_field_async<'r, Info: ?Sized, Ctx: ?Sized>( + &'r self, + field_name: &'r str, + arguments: &'r Arguments<S>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> + where + Self: resolve::FieldAsync<Info, Ctx, S>, + { + <Self as resolve::FieldAsync<Info, Ctx, S>>::resolve_field_async( + self, field_name, arguments, info, executor, + ) + } +} diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index fa869cbd..d9b4979c 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -41,7 +41,7 @@ pub(crate) mod schema; mod types; mod util; pub mod validation; -mod value; +pub(crate) mod value; #[cfg(all(test, not(feature = "expose-test-schema")))] mod tests; diff --git a/juniper/src/resolve/mod.rs b/juniper/src/resolve/mod.rs index 27b28a19..e027d0cf 100644 --- a/juniper/src/resolve/mod.rs +++ b/juniper/src/resolve/mod.rs @@ -1,29 +1,76 @@ use crate::{ - executor::{ExecutionResult, Executor, Registry}, - schema::meta::MetaType, - Arguments, DefaultScalarValue, + meta::MetaType, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, Registry, + Selection, }; +pub trait Type<Info: ?Sized, S = DefaultScalarValue> { + fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r; +} + pub trait TypeName<Info: ?Sized> { fn type_name(info: &Info) -> &str; } -pub trait Type<Info: ?Sized, S = DefaultScalarValue> { - fn meta<'r>(info: &Info, registry: &mut Registry<'r, S>) -> MetaType<'r, S> - where - S: 'r; +pub trait ConcreteTypeName<Info: ?Sized> { + fn concrete_type_name<'i>(&self, info: &'i Info) -> &'i str; +} + +pub trait Value<Info: ?Sized, Ctx: ?Sized, S = DefaultScalarValue> { + fn resolve_value( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S>; +} + +pub trait ValueAsync<Info: ?Sized, Ctx: ?Sized, S = DefaultScalarValue> { + fn resolve_value_async<'r>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>>; +} + +pub trait ConcreteValue<Info: ?Sized, Ctx: ?Sized, S = DefaultScalarValue> { + fn resolve_concrete_value( + &self, + type_name: &str, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S>; +} + +pub trait ConcreteValueAsync<Info: ?Sized, Ctx: ?Sized, S = DefaultScalarValue> { + fn resolve_concrete_value_async<'r>( + &'r self, + type_name: &str, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>>; } pub trait Field<Info: ?Sized, Ctx: ?Sized, S = DefaultScalarValue> { fn resolve_field( &self, - info: &Info, field_name: &str, arguments: &Arguments<S>, + info: &Info, executor: &Executor<Ctx, S>, ) -> ExecutionResult<S>; } -pub trait ConcreteTypeName<Info: ?Sized> { - fn concrete_type_name<'i>(&self, info: &'i Info) -> &'i str; +pub trait FieldAsync<Info: ?Sized, Ctx: ?Sized, S = DefaultScalarValue> { + fn resolve_field_async<'r>( + &'r self, + field_name: &'r str, + arguments: &'r Arguments<S>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>>; } diff --git a/juniper/src/types/arc.rs b/juniper/src/types/arc.rs new file mode 100644 index 00000000..8300eec9 --- /dev/null +++ b/juniper/src/types/arc.rs @@ -0,0 +1,186 @@ +use std::sync::Arc; + +use crate::{ + executor::{ExecutionResult, Executor, Registry}, + graphql, resolve, + schema::meta::MetaType, + Arguments, BoxFuture, Selection, +}; + +impl<T, Info, S> resolve::Type<Info, S> for Arc<T> +where + T: resolve::Type<Info, S> + ?Sized, + Info: ?Sized, +{ + fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + { + T::meta(registry, info) + } +} + +impl<T, Info> resolve::TypeName<Info> for Arc<T> +where + T: resolve::TypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn type_name(info: &Info) -> &str { + T::type_name(info) + } +} + +impl<T, Info> resolve::ConcreteTypeName<Info> for Arc<T> +where + T: resolve::ConcreteTypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn concrete_type_name<'i>(&self, info: &'i Info) -> &'i str { + (**self).concrete_type_name(info) + } +} + +impl<T, Info, Ctx, S> resolve::Value<Info, Ctx, S> for Arc<T> +where + T: resolve::Value<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_value(selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ValueAsync<Info, Ctx, S> for Arc<T> +where + T: resolve::ValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value_async<'r>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_value_async(selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ConcreteValue<Info, Ctx, S> for Arc<T> +where + T: resolve::ConcreteValue<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value( + &self, + type_name: &str, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_concrete_value(type_name, selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ConcreteValueAsync<Info, Ctx, S> for Arc<T> +where + T: resolve::ConcreteValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value_async<'r>( + &'r self, + type_name: &str, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_concrete_value_async(type_name, selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::Field<Info, Ctx, S> for Arc<T> +where + T: resolve::Field<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field( + &self, + field_name: &str, + arguments: &Arguments<S>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_field(field_name, arguments, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::FieldAsync<Info, Ctx, S> for Arc<T> +where + T: resolve::FieldAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field_async<'r>( + &'r self, + field_name: &'r str, + arguments: &'r Arguments<S>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_field_async(field_name, arguments, info, executor) + } +} + +impl<T, S> graphql::InputType<S> for Arc<T> +where + T: graphql::InputType<S> + ?Sized, +{ + fn assert_input_type() { + T::assert_input_type() + } +} + +impl<T, S> graphql::OutputType<S> for Arc<T> +where + T: graphql::OutputType<S> + ?Sized, +{ + fn assert_output_type() { + T::assert_output_type() + } +} + +impl<T, S> graphql::Interface<S> for Arc<T> +where + T: graphql::Interface<S> + ?Sized, +{ + fn assert_interface() { + T::assert_interface() + } +} + +impl<T, S> graphql::Object<S> for Arc<T> +where + T: graphql::Object<S> + ?Sized, +{ + fn assert_object() { + T::assert_object() + } +} + +impl<T, S> graphql::Union<S> for Arc<T> +where + T: graphql::Union<S> + ?Sized, +{ + fn assert_union() { + T::assert_union() + } +} diff --git a/juniper/src/types/box.rs b/juniper/src/types/box.rs new file mode 100644 index 00000000..5f0b0ce1 --- /dev/null +++ b/juniper/src/types/box.rs @@ -0,0 +1,184 @@ +use crate::{ + executor::{ExecutionResult, Executor, Registry}, + graphql, resolve, + schema::meta::MetaType, + Arguments, BoxFuture, Selection, +}; + +impl<T, Info, S> resolve::Type<Info, S> for Box<T> +where + T: resolve::Type<Info, S> + ?Sized, + Info: ?Sized, +{ + fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + { + T::meta(registry, info) + } +} + +impl<T, Info> resolve::TypeName<Info> for Box<T> +where + T: resolve::TypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn type_name(info: &Info) -> &str { + T::type_name(info) + } +} + +impl<T, Info> resolve::ConcreteTypeName<Info> for Box<T> +where + T: resolve::ConcreteTypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn concrete_type_name<'i>(&self, info: &'i Info) -> &'i str { + (**self).concrete_type_name(info) + } +} + +impl<T, Info, Ctx, S> resolve::Value<Info, Ctx, S> for Box<T> +where + T: resolve::Value<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_value(selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ValueAsync<Info, Ctx, S> for Box<T> +where + T: resolve::ValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value_async<'r>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_value_async(selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ConcreteValue<Info, Ctx, S> for Box<T> +where + T: resolve::ConcreteValue<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value( + &self, + type_name: &str, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_concrete_value(type_name, selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ConcreteValueAsync<Info, Ctx, S> for Box<T> +where + T: resolve::ConcreteValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value_async<'r>( + &'r self, + type_name: &str, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_concrete_value_async(type_name, selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::Field<Info, Ctx, S> for Box<T> +where + T: resolve::Field<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field( + &self, + field_name: &str, + arguments: &Arguments<S>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_field(field_name, arguments, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::FieldAsync<Info, Ctx, S> for Box<T> +where + T: resolve::FieldAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field_async<'r>( + &'r self, + field_name: &'r str, + arguments: &'r Arguments<S>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_field_async(field_name, arguments, info, executor) + } +} + +impl<T, S> graphql::InputType<S> for Box<T> +where + T: graphql::InputType<S> + ?Sized, +{ + fn assert_input_type() { + T::assert_input_type() + } +} + +impl<T, S> graphql::OutputType<S> for Box<T> +where + T: graphql::OutputType<S> + ?Sized, +{ + fn assert_output_type() { + T::assert_output_type() + } +} + +impl<T, S> graphql::Interface<S> for Box<T> +where + T: graphql::Interface<S> + ?Sized, +{ + fn assert_interface() { + T::assert_interface() + } +} + +impl<T, S> graphql::Object<S> for Box<T> +where + T: graphql::Object<S> + ?Sized, +{ + fn assert_object() { + T::assert_object() + } +} + +impl<T, S> graphql::Union<S> for Box<T> +where + T: graphql::Union<S> + ?Sized, +{ + fn assert_union() { + T::assert_union() + } +} diff --git a/juniper/src/types/iter.rs b/juniper/src/types/iter.rs new file mode 100644 index 00000000..2b4e5edd --- /dev/null +++ b/juniper/src/types/iter.rs @@ -0,0 +1,65 @@ +use crate::{graphql, resolve, ExecutionResult, Executor, Selection}; + +pub fn resolve_list<'t, T, S, Info, Ctx, I>( + iter: I, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, +) -> ExecutionResult<S> +where + I: Iterator<Item = &'t T> + ExactSizeIterator, + T: resolve::Value<Info, Ctx, S> + ?Sized + 't, + Info: ?Sized, + Ctx: ?Sized, +{ + let is_non_null = executor + .current_type_new() + .list_contents() + .ok_or("Iterating over non-list type")? + .is_non_null(); + + let mut values = Vec::with_capacity(iter.len()); + for v in iter { + let val = v.resolve_value(selection_set, info, executor)?; + if is_non_null && val.is_null() { + return Err("Resolved `null` on non-null type".into()); + } + values.push(val); + } + Ok(graphql::Value::list(values)) +} + +pub async fn resolve_list_async<'a, 't, T, S, Info, Ctx, I>( + iter: I, + selection_set: Option<&[Selection<'_, S>]>, + info: &'a Info, + executor: &'a Executor<'a, 'a, Ctx, S>, +) -> ExecutionResult<S> +where + I: Iterator<Item = &'t T> + ExactSizeIterator, + T: resolve::ValueAsync<Info, Ctx, S> + ?Sized + 't, + Info: ?Sized, + Ctx: ?Sized, +{ + use futures::stream::{FuturesOrdered, StreamExt as _}; + + let is_non_null = executor + .current_type_new() + .list_contents() + .ok_or("Iterating over non-list type")? + .is_non_null(); + + let mut futs = iter + .map(|v| async move { v.resolve_value_async(selection_set, info, executor).await }) + .collect::<FuturesOrdered<_>>(); + + let mut values = Vec::with_capacity(futs.len()); + while let Some(res) = futs.next().await { + let val = res?; + if is_non_null && val.is_null() { + return Err("Resolved `null` on non-null type".into()); + } + values.push(val); + } + Ok(graphql::Value::list(values)) +} diff --git a/juniper/src/types/mod.rs b/juniper/src/types/mod.rs index 8ac005ba..55451b5a 100644 --- a/juniper/src/types/mod.rs +++ b/juniper/src/types/mod.rs @@ -1,3 +1,12 @@ +mod arc; +mod r#box; +pub mod iter; +mod option; +mod rc; +mod r#ref; +mod ref_mut; +mod vec; + pub mod async_await; pub mod base; pub mod containers; diff --git a/juniper/src/types/option.rs b/juniper/src/types/option.rs new file mode 100644 index 00000000..98f995c4 --- /dev/null +++ b/juniper/src/types/option.rs @@ -0,0 +1,78 @@ +use futures::future; + +use crate::{ + executor::{ExecutionResult, Executor, Registry}, + graphql, resolve, + schema::meta::MetaType, + BoxFuture, Selection, +}; + +impl<T, Info, S> resolve::Type<Info, S> for Option<T> +where + T: resolve::Type<Info, S>, + Info: ?Sized, +{ + fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + { + registry.build_nullable_type_new::<T, _>(info).into_meta() + } +} + +impl<T, Info, Ctx, S> resolve::Value<Info, Ctx, S> for Option<T> +where + T: resolve::Value<Info, Ctx, S>, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + match self { + Some(v) => v.resolve_value(selection_set, info, executor), + None => Ok(graphql::Value::Null), + } + } +} + +impl<T, Info, Ctx, S> resolve::ValueAsync<Info, Ctx, S> for Option<T> +where + T: resolve::ValueAsync<Info, Ctx, S>, + Info: ?Sized, + Ctx: ?Sized, + S: Send, +{ + fn resolve_value_async<'r>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + match self { + Some(v) => v.resolve_value_async(selection_set, info, executor), + None => Box::pin(future::ok(graphql::Value::Null)), + } + } +} + +impl<T, S> graphql::InputType<S> for Option<T> +where + T: graphql::InputType<S>, +{ + fn assert_input_type() { + T::assert_input_type() + } +} + +impl<T, S> graphql::OutputType<S> for Option<T> +where + T: graphql::OutputType<S>, +{ + fn assert_output_type() { + T::assert_output_type() + } +} diff --git a/juniper/src/types/rc.rs b/juniper/src/types/rc.rs new file mode 100644 index 00000000..0ac2d263 --- /dev/null +++ b/juniper/src/types/rc.rs @@ -0,0 +1,186 @@ +use std::rc::Rc; + +use crate::{ + executor::{ExecutionResult, Executor, Registry}, + graphql, resolve, + schema::meta::MetaType, + Arguments, BoxFuture, Selection, +}; + +impl<T, Info, S> resolve::Type<Info, S> for Rc<T> +where + T: resolve::Type<Info, S> + ?Sized, + Info: ?Sized, +{ + fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + { + T::meta(registry, info) + } +} + +impl<T, Info> resolve::TypeName<Info> for Rc<T> +where + T: resolve::TypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn type_name(info: &Info) -> &str { + T::type_name(info) + } +} + +impl<T, Info> resolve::ConcreteTypeName<Info> for Rc<T> +where + T: resolve::ConcreteTypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn concrete_type_name<'i>(&self, info: &'i Info) -> &'i str { + (**self).concrete_type_name(info) + } +} + +impl<T, Info, Ctx, S> resolve::Value<Info, Ctx, S> for Rc<T> +where + T: resolve::Value<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_value(selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ValueAsync<Info, Ctx, S> for Rc<T> +where + T: resolve::ValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value_async<'r>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_value_async(selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ConcreteValue<Info, Ctx, S> for Rc<T> +where + T: resolve::ConcreteValue<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value( + &self, + type_name: &str, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_concrete_value(type_name, selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ConcreteValueAsync<Info, Ctx, S> for Rc<T> +where + T: resolve::ConcreteValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value_async<'r>( + &'r self, + type_name: &str, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_concrete_value_async(type_name, selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::Field<Info, Ctx, S> for Rc<T> +where + T: resolve::Field<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field( + &self, + field_name: &str, + arguments: &Arguments<S>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_field(field_name, arguments, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::FieldAsync<Info, Ctx, S> for Rc<T> +where + T: resolve::FieldAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field_async<'r>( + &'r self, + field_name: &'r str, + arguments: &'r Arguments<S>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_field_async(field_name, arguments, info, executor) + } +} + +impl<T, S> graphql::InputType<S> for Rc<T> +where + T: graphql::InputType<S> + ?Sized, +{ + fn assert_input_type() { + T::assert_input_type() + } +} + +impl<T, S> graphql::OutputType<S> for Rc<T> +where + T: graphql::OutputType<S> + ?Sized, +{ + fn assert_output_type() { + T::assert_output_type() + } +} + +impl<T, S> graphql::Interface<S> for Rc<T> +where + T: graphql::Interface<S> + ?Sized, +{ + fn assert_interface() { + T::assert_interface() + } +} + +impl<T, S> graphql::Object<S> for Rc<T> +where + T: graphql::Object<S> + ?Sized, +{ + fn assert_object() { + T::assert_object() + } +} + +impl<T, S> graphql::Union<S> for Rc<T> +where + T: graphql::Union<S> + ?Sized, +{ + fn assert_union() { + T::assert_union() + } +} diff --git a/juniper/src/types/ref.rs b/juniper/src/types/ref.rs new file mode 100644 index 00000000..2f086794 --- /dev/null +++ b/juniper/src/types/ref.rs @@ -0,0 +1,182 @@ +use crate::{ + graphql, meta::MetaType, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, + Selection, +}; + +impl<'me, T, Info, S> resolve::Type<Info, S> for &'me T +where + T: resolve::Type<Info, S> + ?Sized, + Info: ?Sized, +{ + fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + { + T::meta(registry, info) + } +} + +impl<'me, T, Info> resolve::TypeName<Info> for &'me T +where + T: resolve::TypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn type_name(info: &Info) -> &str { + T::type_name(info) + } +} + +impl<'me, T, Info> resolve::ConcreteTypeName<Info> for &'me T +where + T: resolve::ConcreteTypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn concrete_type_name<'i>(&self, info: &'i Info) -> &'i str { + (**self).concrete_type_name(info) + } +} + +impl<'me, T, Info, Ctx, S> resolve::Value<Info, Ctx, S> for &'me T +where + T: resolve::Value<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_value(selection_set, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::ValueAsync<Info, Ctx, S> for &'me T +where + T: resolve::ValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value_async<'r>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_value_async(selection_set, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::ConcreteValue<Info, Ctx, S> for &'me T +where + T: resolve::ConcreteValue<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value( + &self, + type_name: &str, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_concrete_value(type_name, selection_set, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::ConcreteValueAsync<Info, Ctx, S> for &'me T +where + T: resolve::ConcreteValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value_async<'r>( + &'r self, + type_name: &str, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_concrete_value_async(type_name, selection_set, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::Field<Info, Ctx, S> for &'me T +where + T: resolve::Field<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field( + &self, + field_name: &str, + arguments: &Arguments<S>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_field(field_name, arguments, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::FieldAsync<Info, Ctx, S> for &'me T +where + T: resolve::FieldAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field_async<'r>( + &'r self, + field_name: &'r str, + arguments: &'r Arguments<S>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_field_async(field_name, arguments, info, executor) + } +} + +impl<'me, T, S> graphql::InputType<S> for &'me T +where + T: graphql::InputType<S> + ?Sized, +{ + fn assert_input_type() { + T::assert_input_type() + } +} + +impl<'me, T, S> graphql::OutputType<S> for &'me T +where + T: graphql::OutputType<S> + ?Sized, +{ + fn assert_output_type() { + T::assert_output_type() + } +} + +impl<'me, T, S> graphql::Interface<S> for &'me T +where + T: graphql::Interface<S> + ?Sized, +{ + fn assert_interface() { + T::assert_interface() + } +} + +impl<'me, T, S> graphql::Object<S> for &'me T +where + T: graphql::Object<S> + ?Sized, +{ + fn assert_object() { + T::assert_object() + } +} + +impl<'me, T, S> graphql::Union<S> for &'me T +where + T: graphql::Union<S> + ?Sized, +{ + fn assert_union() { + T::assert_union() + } +} diff --git a/juniper/src/types/ref_mut.rs b/juniper/src/types/ref_mut.rs new file mode 100644 index 00000000..566359b6 --- /dev/null +++ b/juniper/src/types/ref_mut.rs @@ -0,0 +1,182 @@ +use crate::{ + graphql, meta::MetaType, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, + Selection, +}; + +impl<'me, T, Info, S> resolve::Type<Info, S> for &'me mut T +where + T: resolve::Type<Info, S> + ?Sized, + Info: ?Sized, +{ + fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + { + T::meta(registry, info) + } +} + +impl<'me, T, Info> resolve::TypeName<Info> for &'me mut T +where + T: resolve::TypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn type_name(info: &Info) -> &str { + T::type_name(info) + } +} + +impl<'me, T, Info> resolve::ConcreteTypeName<Info> for &'me mut T +where + T: resolve::ConcreteTypeName<Info> + ?Sized, + Info: ?Sized, +{ + fn concrete_type_name<'i>(&self, info: &'i Info) -> &'i str { + (**self).concrete_type_name(info) + } +} + +impl<'me, T, Info, Ctx, S> resolve::Value<Info, Ctx, S> for &'me mut T +where + T: resolve::Value<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_value(selection_set, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::ValueAsync<Info, Ctx, S> for &'me mut T +where + T: resolve::ValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value_async<'r>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_value_async(selection_set, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::ConcreteValue<Info, Ctx, S> for &'me mut T +where + T: resolve::ConcreteValue<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value( + &self, + type_name: &str, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_concrete_value(type_name, selection_set, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::ConcreteValueAsync<Info, Ctx, S> for &'me mut T +where + T: resolve::ConcreteValueAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_concrete_value_async<'r>( + &'r self, + type_name: &str, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_concrete_value_async(type_name, selection_set, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::Field<Info, Ctx, S> for &'me mut T +where + T: resolve::Field<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field( + &self, + field_name: &str, + arguments: &Arguments<S>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + (**self).resolve_field(field_name, arguments, info, executor) + } +} + +impl<'me, T, Info, Ctx, S> resolve::FieldAsync<Info, Ctx, S> for &'me mut T +where + T: resolve::FieldAsync<Info, Ctx, S> + ?Sized, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_field_async<'r>( + &'r self, + field_name: &'r str, + arguments: &'r Arguments<S>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + (**self).resolve_field_async(field_name, arguments, info, executor) + } +} + +impl<'me, T, S> graphql::InputType<S> for &'me mut T +where + T: graphql::InputType<S> + ?Sized, +{ + fn assert_input_type() { + T::assert_input_type() + } +} + +impl<'me, T, S> graphql::OutputType<S> for &'me mut T +where + T: graphql::OutputType<S> + ?Sized, +{ + fn assert_output_type() { + T::assert_output_type() + } +} + +impl<'me, T, S> graphql::Interface<S> for &'me mut T +where + T: graphql::Interface<S> + ?Sized, +{ + fn assert_interface() { + T::assert_interface() + } +} + +impl<'me, T, S> graphql::Object<S> for &'me mut T +where + T: graphql::Object<S> + ?Sized, +{ + fn assert_object() { + T::assert_object() + } +} + +impl<'me, T, S> graphql::Union<S> for &'me mut T +where + T: graphql::Union<S> + ?Sized, +{ + fn assert_union() { + T::assert_union() + } +} diff --git a/juniper/src/types/vec.rs b/juniper/src/types/vec.rs new file mode 100644 index 00000000..e2374e27 --- /dev/null +++ b/juniper/src/types/vec.rs @@ -0,0 +1,77 @@ +use crate::{ + executor::{ExecutionResult, Executor, Registry}, + graphql, resolve, + schema::meta::MetaType, + BoxFuture, Selection, +}; + +use super::iter; + +impl<T, Info, S> resolve::Type<Info, S> for Vec<T> +where + T: resolve::Type<Info, S>, + Info: ?Sized, +{ + fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> + where + S: 'r, + { + registry.build_list_type_new::<T, _>(info, None).into_meta() + } +} + +impl<T, Info, Ctx, S> resolve::Value<Info, Ctx, S> for Vec<T> +where + T: resolve::Value<Info, Ctx, S>, + Info: ?Sized, + Ctx: ?Sized, +{ + fn resolve_value( + &self, + selection_set: Option<&[Selection<'_, S>]>, + info: &Info, + executor: &Executor<Ctx, S>, + ) -> ExecutionResult<S> { + iter::resolve_list(self.iter(), selection_set, info, executor) + } +} + +impl<T, Info, Ctx, S> resolve::ValueAsync<Info, Ctx, S> for Vec<T> +where + T: resolve::ValueAsync<Info, Ctx, S> + Sync, + Info: Sync + ?Sized, + Ctx: Sync + ?Sized, + S: Send + Sync, +{ + fn resolve_value_async<'r>( + &'r self, + selection_set: Option<&'r [Selection<'_, S>]>, + info: &'r Info, + executor: &'r Executor<Ctx, S>, + ) -> BoxFuture<'r, ExecutionResult<S>> { + Box::pin(iter::resolve_list_async( + self.iter(), + selection_set, + info, + executor, + )) + } +} + +impl<T, S> graphql::InputType<S> for Vec<T> +where + T: graphql::InputType<S>, +{ + fn assert_input_type() { + T::assert_input_type() + } +} + +impl<T, S> graphql::OutputType<S> for Vec<T> +where + T: graphql::OutputType<S>, +{ + fn assert_output_type() { + T::assert_output_type() + } +}