Use Custom BoxFuture type + prepare new resolve result value

This commit is contained in:
Christoph Herzog 2019-08-21 15:20:01 +02:00
parent acd1442cea
commit 4940085c44
9 changed files with 32 additions and 14 deletions

View file

@ -210,6 +210,20 @@ impl<S> FieldError<S> {
/// The result of resolving the value of a field of type `T` /// The result of resolving the value of a field of type `T`
pub type FieldResult<T, S = DefaultScalarValue> = Result<T, FieldError<S>>; pub type FieldResult<T, S = DefaultScalarValue> = Result<T, FieldError<S>>;
/*
pub enum ResolvedValue<'a, S = DefaultScalarValue> {
Value(Value<S>),
Future(crate::BoxFuture<'a, Value<S>>),
}
impl<'a, S> From<Value<S>> for ResolvedValue<'a, S> {
#[inline]
fn from(value: Value<S>) -> Self {
ResolvedValue::Value(value)
}
}
*/
/// The result of resolving an unspecified field /// The result of resolving an unspecified field
pub type ExecutionResult<S = DefaultScalarValue> = Result<Value<S>, FieldError<S>>; pub type ExecutionResult<S = DefaultScalarValue> = Result<Value<S>, FieldError<S>>;

View file

@ -177,8 +177,11 @@ pub use crate::{
}, },
}; };
/// A pinned, boxed future that can be polled.
pub type BoxFuture<'a, T> = std::pin::Pin<Box<dyn std::future::Future<Output = T> + 'a + Send>>;
#[cfg(feature = "async")] #[cfg(feature = "async")]
pub use crate::types::async_await::GraphQLTypeAsync; pub use crate::types::async_await::{GraphQLTypeAsync};
/// An error that prevented query execution /// An error that prevented query execution
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]

View file

@ -94,7 +94,7 @@ where
field_name: &'b str, field_name: &'b str,
arguments: &'b Arguments<S>, arguments: &'b Arguments<S>,
executor: &'b Executor<Self::Context, S>, executor: &'b Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'b, ExecutionResult<S>> { ) -> crate::BoxFuture<'b, ExecutionResult<S>> {
use futures::future::{ready, FutureExt}; use futures::future::{ready, FutureExt};
match field_name { match field_name {
"__schema" | "__type" => { "__schema" | "__type" => {

View file

@ -1,4 +1,3 @@
use futures::future::BoxFuture;
use crate::ast::{Directive, FromInputValue, InputValue, Selection}; use crate::ast::{Directive, FromInputValue, InputValue, Selection};
use crate::value::{Object, ScalarRefValue, ScalarValue, Value}; use crate::value::{Object, ScalarRefValue, ScalarValue, Value};
@ -21,7 +20,7 @@ where
field_name: &'a str, field_name: &'a str,
arguments: &'a Arguments<S>, arguments: &'a Arguments<S>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'a, ExecutionResult<S>> { ) -> BoxFuture<'a, ExecutionResult<S>> {
panic!("resolve_field must be implemented by object types"); panic!("resolve_field must be implemented by object types");
} }
@ -30,7 +29,7 @@ where
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'a, Value<S>> { ) -> BoxFuture<'a, Value<S>> {
if let Some(selection_set) = selection_set { if let Some(selection_set) = selection_set {
resolve_selection_set_into_async(self, info, selection_set, executor) resolve_selection_set_into_async(self, info, selection_set, executor)
} else { } else {
@ -47,7 +46,7 @@ pub(crate) fn resolve_selection_set_into_async<'a, 'e, T, CtxT, S>(
info: &'a T::TypeInfo, info: &'a T::TypeInfo,
selection_set: &'e [Selection<'e, S>], selection_set: &'e [Selection<'e, S>],
executor: &'e Executor<'e, CtxT, S>, executor: &'e Executor<'e, CtxT, S>,
) -> futures::future::BoxFuture<'a, Value<S>> ) -> BoxFuture<'a, Value<S>>
where where
T: GraphQLTypeAsync<S, Context = CtxT>, T: GraphQLTypeAsync<S, Context = CtxT>,
T::TypeInfo: Send + Sync, T::TypeInfo: Send + Sync,
@ -71,8 +70,6 @@ enum AsyncValue<S> {
Nested(Value<S>), Nested(Value<S>),
} }
// type ResolveFuture<'a, S> = BoxFuture<'a, AsyncResolve<S>>;
#[cfg(feature = "async")] #[cfg(feature = "async")]
pub(crate) async fn resolve_selection_set_into_async_recursive<'a, T, CtxT, S>( pub(crate) async fn resolve_selection_set_into_async_recursive<'a, T, CtxT, S>(
instance: &'a T, instance: &'a T,

View file

@ -270,7 +270,7 @@ where
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'a, Value<S>> { ) -> crate::BoxFuture<'a, Value<S>> {
let f = resolve_into_list_async(executor, info, self.iter()); let f = resolve_into_list_async(executor, info, self.iter());
futures::future::FutureExt::boxed(f) futures::future::FutureExt::boxed(f)
} }
@ -290,7 +290,7 @@ where
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'a, Value<S>> { ) -> crate::BoxFuture<'a, Value<S>> {
let f = resolve_into_list_async(executor, info, self.iter()); let f = resolve_into_list_async(executor, info, self.iter());
futures::future::FutureExt::boxed(f) futures::future::FutureExt::boxed(f)
} }
@ -310,7 +310,7 @@ where
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'a, Value<S>> { ) -> crate::BoxFuture<'a, Value<S>> {
let f = async move { let f = async move {
match *self { match *self {
Some(ref obj) => executor.resolve_into_value_async(info, obj).await, Some(ref obj) => executor.resolve_into_value_async(info, obj).await,

View file

@ -151,7 +151,7 @@ where
field_name: &'b str, field_name: &'b str,
arguments: &'b Arguments<S>, arguments: &'b Arguments<S>,
executor: &'b Executor<Self::Context, S>, executor: &'b Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'b, ExecutionResult<S>> { ) -> crate::BoxFuture<'b, ExecutionResult<S>> {
crate::GraphQLTypeAsync::resolve_field_async(&**self, info, field_name, arguments, executor) crate::GraphQLTypeAsync::resolve_field_async(&**self, info, field_name, arguments, executor)
} }
@ -160,7 +160,7 @@ where
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'a, Value<S>> { ) -> crate::BoxFuture<'a, Value<S>> {
crate::GraphQLTypeAsync::resolve_async(&**self, info, selection_set, executor) crate::GraphQLTypeAsync::resolve_async(&**self, info, selection_set, executor)
} }
} }

View file

@ -207,7 +207,7 @@ where
info: &'a Self::TypeInfo, info: &'a Self::TypeInfo,
selection_set: Option<&'a [Selection<S>]>, selection_set: Option<&'a [Selection<S>]>,
executor: &'a Executor<Self::Context, S>, executor: &'a Executor<Self::Context, S>,
) -> futures::future::BoxFuture<'a, crate::Value<S>> { ) -> crate::BoxFuture<'a, crate::Value<S>> {
use futures::future; use futures::future;
future::FutureExt::boxed(future::ready(self.resolve(info, selection_set, executor))) future::FutureExt::boxed(future::ready(self.resolve(info, selection_set, executor)))
} }

View file

@ -120,6 +120,9 @@ where
} }
} }
/// Convert this value into an Object.
///
/// Returns None if value is not an Object.
pub fn into_object(self) -> Option<Object<S>> { pub fn into_object(self) -> Option<Object<S>> {
match self { match self {
Value::Object(o) => Some(o), Value::Object(o) => Some(o),

View file

@ -77,6 +77,7 @@ impl<S> Object<S> {
.map(|&(_, ref value)| value) .map(|&(_, ref value)| value)
} }
/// Recursively sort all keys by field.
pub fn sort_by_field(&mut self) { pub fn sort_by_field(&mut self) {
self.key_value_list self.key_value_list
.sort_by(|(key1, _), (key2, _)| key1.cmp(key2)); .sort_by(|(key1, _), (key2, _)| key1.cmp(key2));