Impl fields resolving, vol.2 [skip ci]
This commit is contained in:
commit
d1f2173109
33 changed files with 337 additions and 209 deletions
|
@ -8,7 +8,7 @@ publish = false
|
|||
[dependencies]
|
||||
async-stream = "0.3"
|
||||
env_logger = "0.9"
|
||||
futures = "0.3.1"
|
||||
futures = "0.3"
|
||||
juniper = { path = "../../juniper" }
|
||||
juniper_graphql_ws = { path = "../../juniper_graphql_ws" }
|
||||
juniper_warp = { path = "../../juniper_warp", features = ["subscriptions"] }
|
||||
|
|
|
@ -40,10 +40,10 @@ anyhow = { version = "1.0.32", default-features = false, optional = true }
|
|||
async-trait = "0.1.39"
|
||||
bigdecimal = { version = "0.3", optional = true }
|
||||
bson = { version = "2.4", features = ["chrono-0_4"], optional = true }
|
||||
chrono = { version = "0.4", features = ["alloc"], default-features = false, optional = true }
|
||||
chrono = { version = "0.4.20", features = ["alloc"], default-features = false, optional = true }
|
||||
chrono-tz = { version = "0.6", default-features = false, optional = true }
|
||||
fnv = "1.0.3"
|
||||
futures = { version = "0.3.1", features = ["alloc"], default-features = false }
|
||||
futures = { version = "0.3.22", features = ["alloc"], default-features = false }
|
||||
futures-enum = { version = "0.1.12", default-features = false }
|
||||
graphql-parser = { version = "0.4", optional = true }
|
||||
indexmap = { version = "1.0", features = ["serde-1"] }
|
||||
|
@ -62,7 +62,7 @@ getrandom = { version = "0.2", features = ["js"] }
|
|||
|
||||
[dev-dependencies]
|
||||
bencher = "0.1.2"
|
||||
chrono = { version = "0.4", features = ["alloc"], default-features = false }
|
||||
chrono = { version = "0.4.20", features = ["alloc"], default-features = false }
|
||||
pretty_assertions = "1.0.0"
|
||||
serde_json = "1.0.2"
|
||||
tokio = { version = "1.0", features = ["macros", "time", "rt-multi-thread"] }
|
||||
|
|
|
@ -96,9 +96,10 @@ mod interface {
|
|||
|
||||
mod union {
|
||||
use crate::{
|
||||
graphql_object, GraphQLUnion, graphql_value,
|
||||
graphql_object, graphql_value,
|
||||
schema::model::RootNode,
|
||||
types::scalars::{EmptyMutation, EmptySubscription},
|
||||
GraphQLUnion,
|
||||
};
|
||||
|
||||
#[derive(GraphQLUnion)]
|
||||
|
|
|
@ -75,6 +75,7 @@ pub use crate::{
|
|||
FromContext, IntoFieldError, IntoResolvable, LookAheadArgument, LookAheadMethods,
|
||||
LookAheadSelection, LookAheadValue, OwnedExecutor, Registry, ValuesStream, Variables,
|
||||
},
|
||||
extract::Extract,
|
||||
introspection::IntrospectionFormat,
|
||||
macros::helper::subscription::{ExtractTypeFromStream, IntoFieldResult},
|
||||
parser::{ParseError, ScalarToken, Spanning},
|
||||
|
@ -95,7 +96,6 @@ pub use crate::{
|
|||
},
|
||||
validation::RuleError,
|
||||
value::{DefaultScalarValue, Object, ParseScalarResult, ParseScalarValue, ScalarValue, Value},
|
||||
extract::Extract,
|
||||
};
|
||||
|
||||
/// An error that prevented query execution
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::{
|
|||
reflect, Arguments, BoxFuture, ExecutionResult, Executor, FieldResult, IntoFieldError,
|
||||
Registry, Selection,
|
||||
};
|
||||
use juniper::resolve;
|
||||
|
||||
pub trait Type<TypeInfo: ?Sized, ScalarValue, Behavior: ?Sized = behavior::Standard> {
|
||||
fn meta<'r, 'ti: 'r>(
|
||||
|
@ -54,6 +53,12 @@ pub trait ValueAsync<
|
|||
) -> BoxFuture<'r, ExecutionResult<ScalarValue>>;
|
||||
}
|
||||
|
||||
pub trait Resolvable<ScalarValue, Behavior: ?Sized = behavior::Standard> {
|
||||
type Value;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self::Value, ScalarValue>;
|
||||
}
|
||||
|
||||
pub trait ConcreteValue<
|
||||
TypeInfo: ?Sized,
|
||||
Context: ?Sized,
|
||||
|
@ -204,75 +209,3 @@ pub trait InputValueAsRef<ScalarValue, Behavior: ?Sized = behavior::Standard> {
|
|||
pub trait ScalarToken<ScalarValue, Behavior: ?Sized = behavior::Standard> {
|
||||
fn parse_scalar_token(token: parser::ScalarToken<'_>) -> Result<ScalarValue, ParseError>;
|
||||
}
|
||||
|
||||
/*
|
||||
pub trait IntoResolvable<
|
||||
ScalarValue,
|
||||
>
|
||||
{
|
||||
type Type;
|
||||
|
||||
fn into_resolvable(self) -> FieldResult<Self::Type, ScalarValue>;
|
||||
}
|
||||
|
||||
impl<T, SV> IntoResolvable<SV> for T
|
||||
where
|
||||
T: crate::GraphQLValue<SV>,
|
||||
SV: crate::ScalarValue,
|
||||
{
|
||||
type Type = Self;
|
||||
|
||||
fn into_resolvable(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E, SV> IntoResolvable<SV> for Result<T, E>
|
||||
where
|
||||
T: crate::GraphQLValue<SV>,
|
||||
SV: crate::ScalarValue,
|
||||
E: IntoFieldError<SV>,
|
||||
{
|
||||
type Type = T;
|
||||
|
||||
fn into_resolvable(self) -> FieldResult<Self::Type, SV> {
|
||||
self.map_err(IntoFieldError::into_field_error)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait IntoResolvable<S, T>
|
||||
where
|
||||
T: crate::GraphQLValue<S>,
|
||||
S: crate::ScalarValue,
|
||||
{
|
||||
type Type;
|
||||
|
||||
#[doc(hidden)]
|
||||
fn into_resolvable(self) -> FieldResult<T, S>;
|
||||
}
|
||||
|
||||
impl<'a, S, T> IntoResolvable<S, T> for T
|
||||
where
|
||||
T: crate::GraphQLValue<S>,
|
||||
S: crate::ScalarValue,
|
||||
{
|
||||
type Type = T;
|
||||
|
||||
fn into_resolvable(self) -> FieldResult<T, S> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S, T, E: IntoFieldError<S>> IntoResolvable<S, T> for Result<T, E>
|
||||
where
|
||||
S: crate::ScalarValue,
|
||||
T: crate::GraphQLValue<S>,
|
||||
{
|
||||
type Type = T;
|
||||
|
||||
fn into_resolvable(self) -> FieldResult<T, S> {
|
||||
self.map_err(IntoFieldError::into_field_error)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ use crate::{
|
|||
graphql,
|
||||
meta::MetaType,
|
||||
parser::{ParseError, ScalarToken},
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, FieldResult, Registry,
|
||||
Selection,
|
||||
};
|
||||
|
||||
impl<T, TI, SV, BH> resolve::Type<TI, SV, BH> for Arc<T>
|
||||
|
@ -79,6 +80,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::Resolvable<SV, BH> for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, TI, CX, SV, BH> resolve::ConcreteValue<TI, CX, SV, BH> for Arc<T>
|
||||
where
|
||||
T: resolve::ConcreteValue<TI, CX, SV, BH> + ?Sized,
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
|||
executor::{ExecutionResult, Executor, Registry},
|
||||
graphql, reflect, resolve,
|
||||
schema::meta::MetaType,
|
||||
BoxFuture, FieldError, IntoFieldError, Selection,
|
||||
BoxFuture, FieldError, FieldResult, IntoFieldError, Selection,
|
||||
};
|
||||
|
||||
use super::iter;
|
||||
|
@ -71,6 +71,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH, const N: usize> resolve::Resolvable<SV, BH> for [T; N]
|
||||
where
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH, const N: usize> resolve::ToInputValue<SV, BH> for [T; N]
|
||||
where
|
||||
T: resolve::ToInputValue<SV, BH>,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::future;
|
||||
|
||||
use crate::{
|
||||
ast::Selection,
|
||||
executor::{ExecutionResult, Executor},
|
||||
|
@ -254,7 +256,7 @@ where
|
|||
let is_non_null = meta_field.field_type.is_non_null();
|
||||
|
||||
let response_name = response_name.to_string();
|
||||
async_values.push(AsyncValueFuture::Field(async move {
|
||||
async_values.push_back(AsyncValueFuture::Field(async move {
|
||||
// TODO: implement custom future type instead of
|
||||
// two-level boxing.
|
||||
let res = instance
|
||||
|
@ -317,12 +319,12 @@ where
|
|||
|
||||
if let Ok(Value::Object(obj)) = sub_result {
|
||||
for (k, v) in obj {
|
||||
async_values.push(AsyncValueFuture::FragmentSpread(async move {
|
||||
AsyncValue::Field(AsyncField {
|
||||
async_values.push_back(AsyncValueFuture::FragmentSpread(
|
||||
future::ready(AsyncValue::Field(AsyncField {
|
||||
name: k,
|
||||
value: Some(v),
|
||||
})
|
||||
}));
|
||||
})),
|
||||
));
|
||||
}
|
||||
} else if let Err(e) = sub_result {
|
||||
sub_exec.push_error_at(e, *start_pos);
|
||||
|
@ -362,19 +364,19 @@ where
|
|||
|
||||
if let Ok(Value::Object(obj)) = sub_result {
|
||||
for (k, v) in obj {
|
||||
async_values.push(AsyncValueFuture::InlineFragment1(async move {
|
||||
AsyncValue::Field(AsyncField {
|
||||
async_values.push_back(AsyncValueFuture::InlineFragment1(
|
||||
future::ready(AsyncValue::Field(AsyncField {
|
||||
name: k,
|
||||
value: Some(v),
|
||||
})
|
||||
}));
|
||||
})),
|
||||
));
|
||||
}
|
||||
} else if let Err(e) = sub_result {
|
||||
sub_exec.push_error_at(e, *start_pos);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
async_values.push(AsyncValueFuture::InlineFragment2(async move {
|
||||
async_values.push_back(AsyncValueFuture::InlineFragment2(async move {
|
||||
let value = resolve_selection_set_into_async(
|
||||
instance,
|
||||
info,
|
||||
|
|
|
@ -4,7 +4,8 @@ use crate::{
|
|||
graphql,
|
||||
meta::MetaType,
|
||||
parser::{ParseError, ScalarToken},
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, FieldResult, Registry,
|
||||
Selection,
|
||||
};
|
||||
|
||||
impl<T, TI, SV, BH> resolve::Type<TI, SV, BH> for Box<T>
|
||||
|
@ -77,6 +78,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::Resolvable<SV, BH> for Box<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, TI, CX, SV, BH> resolve::ConcreteValue<TI, CX, SV, BH> for Box<T>
|
||||
where
|
||||
T: resolve::ConcreteValue<TI, CX, SV, BH> + ?Sized,
|
||||
|
|
|
@ -6,7 +6,8 @@ use crate::{
|
|||
graphql,
|
||||
meta::MetaType,
|
||||
parser::{ParseError, ScalarToken},
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, FieldResult, Registry,
|
||||
Selection,
|
||||
};
|
||||
|
||||
impl<'me, T, TI, SV, BH> resolve::Type<TI, SV, BH> for Cow<'me, T>
|
||||
|
@ -84,6 +85,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'me, T, SV, BH> resolve::Resolvable<SV, BH> for Cow<'me, T>
|
||||
where
|
||||
T: ToOwned + ?Sized + 'me,
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'me, T, TI, CX, SV, BH> resolve::ConcreteValue<TI, CX, SV, BH> for Cow<'me, T>
|
||||
where
|
||||
T: resolve::ConcreteValue<TI, CX, SV, BH> + ToOwned + ?Sized + 'me,
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
|||
base::{GraphQLType, GraphQLValue},
|
||||
marker::IsInputType,
|
||||
},
|
||||
BoxFuture, ScalarValue, Selection,
|
||||
BoxFuture, FieldResult, ScalarValue, Selection,
|
||||
};
|
||||
|
||||
/// [`Nullable`] wrapper allowing to distinguish between an implicit and
|
||||
|
@ -330,6 +330,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::Resolvable<SV, BH> for Nullable<T>
|
||||
where
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::ToInputValue<SV, BH> for Nullable<T>
|
||||
where
|
||||
T: resolve::ToInputValue<SV, BH>,
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
executor::{ExecutionResult, Executor, Registry},
|
||||
graphql, reflect, resolve,
|
||||
schema::meta::MetaType,
|
||||
BoxFuture, Selection,
|
||||
BoxFuture, FieldResult, Selection,
|
||||
};
|
||||
|
||||
impl<T, TI, SV, BH> resolve::Type<TI, SV, BH> for Option<T>
|
||||
|
@ -65,6 +65,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::Resolvable<SV, BH> for Option<T>
|
||||
where
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::ToInputValue<SV, BH> for Option<T>
|
||||
where
|
||||
T: resolve::ToInputValue<SV, BH>,
|
||||
|
|
|
@ -6,7 +6,8 @@ use crate::{
|
|||
graphql,
|
||||
meta::MetaType,
|
||||
parser::{ParseError, ScalarToken},
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, FieldResult, Registry,
|
||||
Selection,
|
||||
};
|
||||
|
||||
impl<T, TI, SV, BH> resolve::Type<TI, SV, BH> for Rc<T>
|
||||
|
@ -79,6 +80,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::Resolvable<SV, BH> for Rc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, TI, CX, SV, BH> resolve::ConcreteValue<TI, CX, SV, BH> for Rc<T>
|
||||
where
|
||||
T: resolve::ConcreteValue<TI, CX, SV, BH> + ?Sized,
|
||||
|
|
|
@ -6,7 +6,8 @@ use crate::{
|
|||
graphql,
|
||||
meta::MetaType,
|
||||
parser::{ParseError, ScalarToken},
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, FieldResult, Registry,
|
||||
Selection,
|
||||
};
|
||||
|
||||
impl<'me, T, TI, SV, BH> resolve::Type<TI, SV, BH> for &'me T
|
||||
|
@ -79,6 +80,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'me, T, SV, BH> resolve::Resolvable<SV, BH> for &'me T
|
||||
where
|
||||
T: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'me, T, TI, CX, SV, BH> resolve::ConcreteValue<TI, CX, SV, BH> for &'me T
|
||||
where
|
||||
T: resolve::ConcreteValue<TI, CX, SV, BH> + ?Sized,
|
||||
|
|
|
@ -6,7 +6,8 @@ use crate::{
|
|||
graphql,
|
||||
meta::MetaType,
|
||||
parser::{ParseError, ScalarToken},
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||
reflect, resolve, Arguments, BoxFuture, ExecutionResult, Executor, FieldResult, Registry,
|
||||
Selection,
|
||||
};
|
||||
|
||||
impl<'me, T, TI, SV, BH> resolve::Type<TI, SV, BH> for &'me mut T
|
||||
|
@ -79,6 +80,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'me, T, SV, BH> resolve::Resolvable<SV, BH> for &'me mut T
|
||||
where
|
||||
T: ?Sized,
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'me, T, TI, CX, SV, BH> resolve::ConcreteValue<TI, CX, SV, BH> for &'me mut T
|
||||
where
|
||||
T: resolve::ConcreteValue<TI, CX, SV, BH> + ?Sized,
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
//! GraphQL implementation for [`Result`].
|
||||
|
||||
use crate::reflect;
|
||||
use crate::{reflect, resolve, FieldResult, IntoFieldError};
|
||||
|
||||
impl<T, E, SV, BH> resolve::Resolvable<SV, BH> for Result<T, E>
|
||||
where
|
||||
E: IntoFieldError<SV>,
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = T;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self::Value, SV> {
|
||||
self.map_err(IntoFieldError::into_field_error)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E, BH> reflect::BaseType<BH> for Result<T, E>
|
||||
where
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
executor::{ExecutionResult, Executor, Registry},
|
||||
graphql, reflect, resolve,
|
||||
schema::meta::MetaType,
|
||||
BoxFuture, FieldError, IntoFieldError, Selection,
|
||||
BoxFuture, FieldError, FieldResult, IntoFieldError, Selection,
|
||||
};
|
||||
|
||||
use super::iter;
|
||||
|
@ -64,6 +64,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::Resolvable<SV, BH> for Vec<T>
|
||||
where
|
||||
BH: ?Sized,
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> FieldResult<Self, SV> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, SV, BH> resolve::ToInputValue<SV, BH> for Vec<T>
|
||||
where
|
||||
T: resolve::ToInputValue<SV, BH>,
|
||||
|
|
|
@ -27,7 +27,7 @@ actix-http = "3.0"
|
|||
actix-web = "4.0"
|
||||
actix-web-actors = "4.1.0"
|
||||
anyhow = "1.0"
|
||||
futures = "0.3"
|
||||
futures = "0.3.22"
|
||||
juniper = { version = "0.16.0-dev", path = "../juniper", default-features = false }
|
||||
juniper_graphql_ws = { version = "0.4.0-dev", path = "../juniper_graphql_ws", optional = true }
|
||||
http = "0.2.4"
|
||||
|
|
|
@ -30,6 +30,6 @@ url = "2.0"
|
|||
|
||||
[dev-dependencies]
|
||||
derive_more = "0.99.7"
|
||||
futures = "0.3"
|
||||
futures = "0.3.22"
|
||||
juniper = { path = "../juniper" }
|
||||
serde = "1.0"
|
||||
|
|
|
@ -417,6 +417,7 @@ impl ToTokens for Definition {
|
|||
self.impl_resolve_type_name().to_tokens(into);
|
||||
self.impl_resolve_value().to_tokens(into);
|
||||
self.impl_resolve_value_async().to_tokens(into);
|
||||
self.impl_resolvable().to_tokens(into);
|
||||
self.impl_resolve_to_input_value().to_tokens(into);
|
||||
self.impl_resolve_input_value().to_tokens(into);
|
||||
self.impl_graphql_input_type().to_tokens(into);
|
||||
|
@ -868,6 +869,31 @@ impl Definition {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns generated code implementing [`resolve::Resolvable`] trait for
|
||||
/// this [GraphQL enum][0].
|
||||
///
|
||||
/// [`resolve::Resolvable`]: juniper::resolve::Resolvable
|
||||
/// [0]: https://spec.graphql.org/October2021#sec-Enums
|
||||
fn impl_resolvable(&self) -> TokenStream {
|
||||
let bh = &self.behavior;
|
||||
let (ty, generics) = self.ty_and_generics();
|
||||
let (sv, generics) = self.mix_scalar_value(generics);
|
||||
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl #impl_gens ::juniper::resolve::Resolvable<#sv, #bh>
|
||||
for #ty #where_clause
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> ::juniper::FieldResult<Self, #sv> {
|
||||
::juniper::FieldResult::Ok(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns generated code implementing [`FromInputValue`] trait for this
|
||||
/// [GraphQL enum][0].
|
||||
///
|
||||
|
|
|
@ -599,108 +599,108 @@ impl<Operation: ?Sized + 'static> Definition<Operation> {
|
|||
})
|
||||
.collect()
|
||||
}
|
||||
/*
|
||||
/// Returns generated code implementing [`resolve::StaticField`] trait for
|
||||
/// each [field][1] of this [GraphQL object][0].
|
||||
///
|
||||
/// [`resolve::StaticField`]: juniper::resolve::StaticField
|
||||
/// [0]: https://spec.graphql.org/October2021#sec-Objects
|
||||
/// [1]: https://spec.graphql.org/October2021#sec-Language.Fields
|
||||
#[must_use]
|
||||
pub(crate) fn impl_resolve_static_field(&self) -> TokenStream {
|
||||
let bh = &self.behavior;
|
||||
let (ty, generics) = self.ty_and_generics();
|
||||
let (inf, generics) = self.mix_type_info(generics);
|
||||
let (cx, generics) = self.mix_context(generics);
|
||||
let (sv, generics) = self.mix_scalar_value(generics);
|
||||
/*
|
||||
/// Returns generated code implementing [`resolve::StaticField`] trait for
|
||||
/// each [field][1] of this [GraphQL object][0].
|
||||
///
|
||||
/// [`resolve::StaticField`]: juniper::resolve::StaticField
|
||||
/// [0]: https://spec.graphql.org/October2021#sec-Objects
|
||||
/// [1]: https://spec.graphql.org/October2021#sec-Language.Fields
|
||||
#[must_use]
|
||||
pub(crate) fn impl_resolve_static_field(&self) -> TokenStream {
|
||||
let bh = &self.behavior;
|
||||
let (ty, generics) = self.ty_and_generics();
|
||||
let (inf, generics) = self.mix_type_info(generics);
|
||||
let (cx, generics) = self.mix_context(generics);
|
||||
let (sv, generics) = self.mix_scalar_value(generics);
|
||||
|
||||
self.fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let mut generics = generics.clone();
|
||||
let (f_name, f_bh) = (&field.name, &field.behavior);
|
||||
let (f_ident, f_ty) = (&field.ident, &field.ty);
|
||||
self.fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let mut generics = generics.clone();
|
||||
let (f_name, f_bh) = (&field.name, &field.behavior);
|
||||
let (f_ident, f_ty) = (&field.ident, &field.ty);
|
||||
|
||||
let body = if !field.is_async {
|
||||
generics.make_where_clause().predicates.push(parse_quote! {
|
||||
#f_ty: ::juniper::resolve::Value<#inf, #cx, #sv, #f_bh>
|
||||
});
|
||||
let body = if !field.is_async {
|
||||
generics.make_where_clause().predicates.push(parse_quote! {
|
||||
#f_ty: ::juniper::resolve::Value<#inf, #cx, #sv, #f_bh>
|
||||
});
|
||||
|
||||
let res = if field.is_method() {
|
||||
let args = field.arguments.as_ref().unwrap().iter().map(|arg| {
|
||||
match arg {
|
||||
field::MethodArgument::Regular(arg) => {
|
||||
let (a_ty, a_bh) = (&arg.ty, &arg.behavior);
|
||||
generics.make_where_clause().predicates.push(parse_quote! {
|
||||
#a_ty: ::juniper::resolve::InputValueOwned<#sv, #a_bh>
|
||||
});
|
||||
quote! {
|
||||
args.resolve::<#a_ty, #a_bh>(#name)?
|
||||
}
|
||||
}
|
||||
field::MethodArgument::Context(cx_ty) => {
|
||||
generics.make_where_clause().predicates.push(parse_quote! {
|
||||
#cx: ::juniper::Extract<#cx_ty>
|
||||
});
|
||||
quote! {
|
||||
<#cx as ::juniper::Extract<#cx_ty>>
|
||||
::extract(executor.context())
|
||||
}
|
||||
}
|
||||
field::MethodArgument::Executor => {
|
||||
quote! {
|
||||
executor
|
||||
let res = if field.is_method() {
|
||||
let args = field.arguments.as_ref().unwrap().iter().map(|arg| {
|
||||
match arg {
|
||||
field::MethodArgument::Regular(arg) => {
|
||||
let (a_ty, a_bh) = (&arg.ty, &arg.behavior);
|
||||
generics.make_where_clause().predicates.push(parse_quote! {
|
||||
#a_ty: ::juniper::resolve::InputValueOwned<#sv, #a_bh>
|
||||
});
|
||||
quote! {
|
||||
args.resolve::<#a_ty, #a_bh>(#name)?
|
||||
}
|
||||
}
|
||||
field::MethodArgument::Context(cx_ty) => {
|
||||
generics.make_where_clause().predicates.push(parse_quote! {
|
||||
#cx: ::juniper::Extract<#cx_ty>
|
||||
});
|
||||
quote! {
|
||||
<#cx as ::juniper::Extract<#cx_ty>>
|
||||
::extract(executor.context())
|
||||
}
|
||||
}
|
||||
field::MethodArgument::Executor => {
|
||||
quote! {
|
||||
executor
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let rcv = field.has_receiver.then(|| {
|
||||
quote! { self, }
|
||||
});
|
||||
|
||||
quote! { Self::#ident(#rcv #( #args ),*) }
|
||||
} else {
|
||||
quote! {
|
||||
&self.#f_ident
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let rcv = field.has_receiver.then(|| {
|
||||
quote! { self, }
|
||||
});
|
||||
|
||||
quote! { Self::#ident(#rcv #( #args ),*) }
|
||||
quote! {
|
||||
executor.resolve_value::<#f_bh, _, _>(#res, type_info)
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
&self.#f_ident
|
||||
::std::panic!(
|
||||
"Tried to resolve async field `{}` on type `{}` with a sync resolver",
|
||||
#f_name,
|
||||
<Self as ::juniper::reflect::BaseType<#bh>>::NAME,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
executor.resolve_value::<#f_bh, _, _>(#res, type_info)
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
::std::panic!(
|
||||
"Tried to resolve async field `{}` on type `{}` with a sync resolver",
|
||||
#f_name,
|
||||
<Self as ::juniper::reflect::BaseType<#bh>>::NAME,
|
||||
);
|
||||
}
|
||||
};
|
||||
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||
|
||||
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl #impl_gens ::juniper::resolve::StaticField<
|
||||
{ ::juniper::reflect::fnv1a128(#f_name) },
|
||||
#inf, #cx, #sv, #bh,
|
||||
> for #ty #where_clause {
|
||||
fn resolve_static_field(
|
||||
&self,
|
||||
args: &::juniper::Arguments<'_, #sv>,
|
||||
type_info: &#inf,
|
||||
executor: &::juniper::Executor<'_, '_, #cx, #sv>,
|
||||
) -> ::juniper::ExecutionResult<#sv> {
|
||||
#body
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl #impl_gens ::juniper::resolve::StaticField<
|
||||
{ ::juniper::reflect::fnv1a128(#f_name) },
|
||||
#inf, #cx, #sv, #bh,
|
||||
> for #ty #where_clause {
|
||||
fn resolve_static_field(
|
||||
&self,
|
||||
args: &::juniper::Arguments<'_, #sv>,
|
||||
type_info: &#inf,
|
||||
executor: &::juniper::Executor<'_, '_, #cx, #sv>,
|
||||
) -> ::juniper::ExecutionResult<#sv> {
|
||||
#body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
*/
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
*/
|
||||
/// Returns generated code implementing [`GraphQLType`] trait for this
|
||||
/// [GraphQL object][1].
|
||||
///
|
||||
|
|
|
@ -351,6 +351,7 @@ impl ToTokens for Definition {
|
|||
self.impl_resolve_type_name().to_tokens(into);
|
||||
self.impl_resolve_value().to_tokens(into);
|
||||
self.impl_resolve_value_async().to_tokens(into);
|
||||
self.impl_resolvable().to_tokens(into);
|
||||
self.impl_resolve_to_input_value().to_tokens(into);
|
||||
self.impl_resolve_input_value().to_tokens(into);
|
||||
self.impl_resolve_scalar_token().to_tokens(into);
|
||||
|
@ -738,6 +739,31 @@ impl Definition {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns generated code implementing [`resolve::Resolvable`] trait for
|
||||
/// this [GraphQL scalar][0].
|
||||
///
|
||||
/// [`resolve::Resolvable`]: juniper::resolve::Resolvable
|
||||
/// [0]: https://spec.graphql.org/October2021#sec-Scalars
|
||||
fn impl_resolvable(&self) -> TokenStream {
|
||||
let bh = &self.behavior;
|
||||
let (ty, generics) = self.ty_and_generics();
|
||||
let (sv, generics) = self.mix_scalar_value(generics);
|
||||
let (impl_gens, _, where_clause) = generics.split_for_impl();
|
||||
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl #impl_gens ::juniper::resolve::Resolvable<#sv, #bh>
|
||||
for #ty #where_clause
|
||||
{
|
||||
type Value = Self;
|
||||
|
||||
fn into_value(self) -> ::juniper::FieldResult<Self, #sv> {
|
||||
::juniper::FieldResult::Ok(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns generated code implementing [`InputValue`] trait for this
|
||||
/// [GraphQL scalar][1].
|
||||
///
|
||||
|
|
|
@ -18,7 +18,7 @@ use syn::{
|
|||
};
|
||||
|
||||
use crate::common::{
|
||||
filter_attrs, gen, behavior,
|
||||
behavior, filter_attrs, gen,
|
||||
parse::{
|
||||
attr::{err, OptionExt as _},
|
||||
ParseBufferExt as _,
|
||||
|
|
|
@ -15,7 +15,7 @@ keywords = ["apollo", "graphql", "hyper", "juniper"]
|
|||
exclude = ["/examples/", "/release.toml"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
futures = "0.3.22"
|
||||
hyper = { version = "0.14", features = ["server", "runtime"] }
|
||||
juniper = { version = "0.16.0-dev", path = "../juniper", default-features = false }
|
||||
serde_json = "1.0"
|
||||
|
|
|
@ -18,7 +18,7 @@ keywords = ["apollo", "graphql", "iron", "juniper"]
|
|||
exclude = ["/examples/", "/release.toml"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
futures = "0.3.22"
|
||||
iron = ">= 0.5, < 0.7"
|
||||
juniper = { version = "0.16.0-dev", path = "../juniper", default-features = false }
|
||||
serde_json = "1.0.2"
|
||||
|
|
|
@ -18,7 +18,7 @@ keywords = ["apollo", "graphql", "juniper", "rocket"]
|
|||
exclude = ["/examples/", "/tests/", "/release.toml"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
futures = "0.3.22"
|
||||
juniper = { version = "0.16.0-dev", path = "../juniper", default-features = false }
|
||||
rocket = { version = "=0.5.0-rc.2", default-features = false }
|
||||
serde_json = "1.0.2"
|
||||
|
|
|
@ -15,7 +15,7 @@ keywords = ["graphql", "server", "subscription", "web", "websocket"]
|
|||
exclude = ["/release.toml"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3.1"
|
||||
futures = "0.3.22"
|
||||
juniper = { version = "0.16.0-dev", path = "../juniper", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -23,7 +23,7 @@ subscriptions = ["juniper_graphql_ws"]
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
futures = "0.3.1"
|
||||
futures = "0.3.22"
|
||||
juniper = { version = "0.16.0-dev", path = "../juniper", default-features = false }
|
||||
juniper_graphql_ws = { version = "0.4.0-dev", path = "../juniper_graphql_ws", optional = true }
|
||||
serde = { version = "1.0.75", features = ["derive"] }
|
||||
|
|
|
@ -8,7 +8,7 @@ publish = false
|
|||
rustversion = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
futures = "0.3.1"
|
||||
futures = "0.3"
|
||||
juniper = { path = "../../juniper" }
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1.0", features = ["rt", "time", "macros"] }
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
error[E0277]: the trait bound `[bool; 2]: From<[bool; 3]>` is not satisfied
|
||||
--> fail/interface/trait/argument_wrong_default_array.rs:3:1
|
||||
--> fail/interface/trait/argument_wrong_default_array.rs:5:41
|
||||
|
|
||||
3 | #[graphql_interface]
|
||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `From<[bool; 3]>` is not implemented for `[bool; 2]`
|
||||
| -------------------- required by a bound introduced by this call
|
||||
4 | trait Character {
|
||||
5 | fn wrong(&self, #[graphql(default = [true, false, false])] input: [bool; 2]) -> bool;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `From<[bool; 3]>` is not implemented for `[bool; 2]`
|
||||
|
|
||||
= help: the following other types implement trait `From<T>`:
|
||||
<&'a [ascii::ascii_char::AsciiChar] as From<&'a ascii::ascii_str::AsciiStr>>
|
||||
|
@ -14,5 +17,4 @@ error[E0277]: the trait bound `[bool; 2]: From<[bool; 3]>` is not satisfied
|
|||
<[u128; 1] as From<ppv_lite86::x86_64::vec128_storage>>
|
||||
<[u128; 2] as From<ppv_lite86::x86_64::vec256_storage>>
|
||||
and 7 others
|
||||
= note: required because of the requirements on the impl of `Into<[bool; 2]>` for `[bool; 3]`
|
||||
= note: this error originates in the attribute macro `graphql_interface` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: required for `[bool; 3]` to implement `Into<[bool; 2]>`
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
error[E0277]: the trait bound `[bool; 2]: From<[bool; 3]>` is not satisfied
|
||||
--> fail/object/argument_wrong_default_array.rs:5:1
|
||||
--> fail/object/argument_wrong_default_array.rs:7:41
|
||||
|
|
||||
5 | #[graphql_object]
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `From<[bool; 3]>` is not implemented for `[bool; 2]`
|
||||
| ----------------- required by a bound introduced by this call
|
||||
6 | impl ObjA {
|
||||
7 | fn wrong(&self, #[graphql(default = [true, false, false])] input: [bool; 2]) -> bool {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `From<[bool; 3]>` is not implemented for `[bool; 2]`
|
||||
|
|
||||
= help: the following other types implement trait `From<T>`:
|
||||
<&'a [ascii::ascii_char::AsciiChar] as From<&'a ascii::ascii_str::AsciiStr>>
|
||||
|
@ -14,5 +17,4 @@ error[E0277]: the trait bound `[bool; 2]: From<[bool; 3]>` is not satisfied
|
|||
<[u128; 1] as From<ppv_lite86::x86_64::vec128_storage>>
|
||||
<[u128; 2] as From<ppv_lite86::x86_64::vec256_storage>>
|
||||
and 7 others
|
||||
= note: required because of the requirements on the impl of `Into<[bool; 2]>` for `[bool; 3]`
|
||||
= note: this error originates in the attribute macro `graphql_object` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: required for `[bool; 3]` to implement `Into<[bool; 2]>`
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
error[E0277]: the trait bound `[bool; 2]: From<[bool; 3]>` is not satisfied
|
||||
--> fail/subscription/argument_wrong_default_array.rs:10:1
|
||||
--> fail/subscription/argument_wrong_default_array.rs:14:29
|
||||
|
|
||||
10 | #[graphql_subscription]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<[bool; 3]>` is not implemented for `[bool; 2]`
|
||||
| ----------------------- required by a bound introduced by this call
|
||||
...
|
||||
14 | #[graphql(default = [true, false, false])] input: [bool; 2],
|
||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `From<[bool; 3]>` is not implemented for `[bool; 2]`
|
||||
|
|
||||
= help: the following other types implement trait `From<T>`:
|
||||
<&'a [ascii::ascii_char::AsciiChar] as From<&'a ascii::ascii_str::AsciiStr>>
|
||||
|
@ -14,5 +17,4 @@ error[E0277]: the trait bound `[bool; 2]: From<[bool; 3]>` is not satisfied
|
|||
<[u128; 1] as From<ppv_lite86::x86_64::vec128_storage>>
|
||||
<[u128; 2] as From<ppv_lite86::x86_64::vec256_storage>>
|
||||
and 7 others
|
||||
= note: required because of the requirements on the impl of `Into<[bool; 2]>` for `[bool; 3]`
|
||||
= note: this error originates in the attribute macro `graphql_subscription` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: required for `[bool; 3]` to implement `Into<[bool; 2]>`
|
||||
|
|
|
@ -6,7 +6,7 @@ publish = false
|
|||
|
||||
[dev-dependencies]
|
||||
async-trait = "0.1.39"
|
||||
chrono = "0.4"
|
||||
chrono = { version = "0.4.20", default-features = false }
|
||||
derive_more = "0.99"
|
||||
fnv = "1.0"
|
||||
futures = "0.3"
|
||||
|
|
Loading…
Reference in a new issue