Impl some basic types

This commit is contained in:
tyranron 2022-04-22 16:48:19 +03:00
parent d00549968c
commit 2d1e5d38b7
No known key found for this signature in database
GPG key ID: 762E144FB230A4F0
14 changed files with 1523 additions and 61 deletions

View file

@ -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,

View file

@ -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();
}

View file

@ -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,
)
}
}

View file

@ -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;

View file

@ -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>>;
}

186
juniper/src/types/arc.rs Normal file
View file

@ -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()
}
}

184
juniper/src/types/box.rs Normal file
View file

@ -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()
}
}

65
juniper/src/types/iter.rs Normal file
View file

@ -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))
}

View file

@ -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;

View file

@ -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()
}
}

186
juniper/src/types/rc.rs Normal file
View file

@ -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()
}
}

182
juniper/src/types/ref.rs Normal file
View file

@ -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()
}
}

View file

@ -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()
}
}

77
juniper/src/types/vec.rs Normal file
View file

@ -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()
}
}