finchers_juniper/execute/
mod.rs

1//! GraphQL executors.
2//!
3//! In order to choose the strategy for executing GraphQL queries,
4//! the following GraphQL executors are provided:
5//!
6//! * [`Nonblocking`]
7//!   It spawns the task for executing GraphQL queries by using the Tokio's
8//!   default executor.  It also notify the start of the blocking section to
9//!   the runtime by using the blocking API provided by `tokio_threadpool`.
10//!
11//! * [`CurrentThread`]
12//!   It executes the GraphQL queries on the current thread.
13//!
14//! * [`WithSpawner`]
15//!   It spawn the task for executing GraphQL queries by using the specified
16//!   task executor. Unlike to `Nonblocking`, it does not notify the start of
17//!   blocking section to the runtime.
18//!
19//! [`Nonblocking`]: ./struct.Nonblocking.html
20//! [`CurrentThread`]: ./struct.CurrentThread.html
21//! [`WithSpawner`]: ./struct.WithSpawner.html
22
23mod current_thread;
24mod nonblocking;
25mod with_spawner;
26
27pub use self::current_thread::{current_thread, CurrentThread};
28pub use self::nonblocking::{nonblocking, Nonblocking};
29pub use self::with_spawner::{with_spawner, WithSpawner};
30
31pub use self::schema::Schema;
32pub use self::shared::SharedSchema;
33
34// ====
35
36mod schema {
37    use juniper::{GraphQLType, RootNode};
38    use std::rc::Rc;
39    use std::sync::Arc;
40
41    /// Trait representing a GraphQL schema.
42    pub trait Schema: SchemaImpl {}
43
44    impl<QueryT, MutationT, CtxT> Schema for RootNode<'static, QueryT, MutationT>
45    where
46        QueryT: GraphQLType<Context = CtxT>,
47        MutationT: GraphQLType<Context = CtxT>,
48    {}
49    impl<S: Schema> Schema for Box<S> {}
50    impl<S: Schema> Schema for Rc<S> {}
51    impl<S: Schema> Schema for Arc<S> {}
52
53    pub trait SchemaImpl {
54        type Context;
55        type Query: GraphQLType<Context = Self::Context>;
56        type Mutation: GraphQLType<Context = Self::Context>;
57        fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation>;
58    }
59
60    impl<QueryT, MutationT, CtxT> SchemaImpl for RootNode<'static, QueryT, MutationT>
61    where
62        QueryT: GraphQLType<Context = CtxT>,
63        MutationT: GraphQLType<Context = CtxT>,
64    {
65        type Context = CtxT;
66        type Query = QueryT;
67        type Mutation = MutationT;
68
69        #[inline]
70        fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation> {
71            self
72        }
73    }
74
75    impl<T: Schema> SchemaImpl for Box<T> {
76        type Context = T::Context;
77        type Query = T::Query;
78        type Mutation = T::Mutation;
79
80        #[inline]
81        fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation> {
82            (**self).as_root_node()
83        }
84    }
85
86    impl<T: Schema> SchemaImpl for Rc<T> {
87        type Context = T::Context;
88        type Query = T::Query;
89        type Mutation = T::Mutation;
90
91        #[inline]
92        fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation> {
93            (**self).as_root_node()
94        }
95    }
96
97    impl<T: Schema> SchemaImpl for Arc<T> {
98        type Context = T::Context;
99        type Query = T::Query;
100        type Mutation = T::Mutation;
101
102        #[inline]
103        fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation> {
104            (**self).as_root_node()
105        }
106    }
107}
108
109mod shared {
110    use super::Schema;
111    use juniper::{GraphQLType, RootNode};
112
113    /// A helper trait for representing a `Schema` which can be shared between threads.
114    #[allow(missing_docs)]
115    pub trait SharedSchema: SharedSchemaImpl {}
116
117    impl<S> SharedSchema for S
118    where
119        S: Schema + Send + Sync + 'static,
120        S::Context: Send + 'static,
121        S::Query: Send + Sync + 'static,
122        S::Mutation: Send + Sync + 'static,
123        <S::Query as GraphQLType>::TypeInfo: Send + Sync + 'static,
124        <S::Mutation as GraphQLType>::TypeInfo: Send + Sync + 'static,
125    {}
126
127    pub trait SharedSchemaImpl: Send + Sync + 'static {
128        type Context: Send + 'static;
129        type QueryTypeInfo: Send + Sync + 'static;
130        type MutationTypeInfo: Send + Sync + 'static;
131        type Query: GraphQLType<Context = Self::Context, TypeInfo = Self::QueryTypeInfo>
132            + Send
133            + Sync
134            + 'static;
135        type Mutation: GraphQLType<Context = Self::Context, TypeInfo = Self::MutationTypeInfo>
136            + Send
137            + Sync
138            + 'static;
139        fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation>;
140    }
141
142    impl<S> SharedSchemaImpl for S
143    where
144        S: Schema + Send + Sync + 'static,
145        S::Context: Send + 'static,
146        S::Query: Send + Sync + 'static,
147        S::Mutation: Send + Sync + 'static,
148        <S::Query as GraphQLType>::TypeInfo: Send + Sync + 'static,
149        <S::Mutation as GraphQLType>::TypeInfo: Send + Sync + 'static,
150    {
151        type Context = S::Context;
152        type Query = S::Query;
153        type Mutation = S::Mutation;
154        type QueryTypeInfo = <S::Query as GraphQLType>::TypeInfo;
155        type MutationTypeInfo = <S::Mutation as GraphQLType>::TypeInfo;
156
157        #[inline]
158        fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation> {
159            self.as_root_node()
160        }
161    }
162}