Poking with parsing input
This commit is contained in:
parent
ffc42b16a1
commit
912d31f66b
9 changed files with 123 additions and 37 deletions
|
@ -4,7 +4,6 @@ use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
convert::TryFrom,
|
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
@ -1295,22 +1294,30 @@ impl<'r, S: 'r> Registry<'r, S> {
|
||||||
ScalarMeta::new::<T>(Cow::Owned(name.to_string()))
|
ScalarMeta::new::<T>(Cow::Owned(name.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
/// Builds a [`ScalarMeta`] information for the specified [`graphql::Type`].
|
/// Builds a [`ScalarMeta`] information for the specified [`graphql::Type`].
|
||||||
///
|
///
|
||||||
/// [`graphql::Type`]: resolve::Type
|
/// [`graphql::Type`]: resolve::Type
|
||||||
pub fn build_scalar_type_new<'info, T, Info>(&mut self, info: &Info) -> ScalarMeta<'r, S>
|
pub fn build_scalar_type_new<T, Info>(&mut self, info: &Info) -> ScalarMeta<'r, S>
|
||||||
where
|
where
|
||||||
T: resolve::TypeName<Info>
|
T: resolve::TypeName<Info> + resolve::ScalarToken<S> + resolve::InputValueOwned<S>,
|
||||||
+ resolve::ScalarToken<S>
|
|
||||||
+ for<'inp> resolve::InputValue<'inp, S>,
|
|
||||||
for<'i> <T as TryFrom<&'i InputValue<S>>>::Error: IntoFieldError<S>,
|
|
||||||
Info: ?Sized,
|
Info: ?Sized,
|
||||||
{
|
{
|
||||||
// TODO: Allow using references.
|
// TODO: Allow using references.
|
||||||
ScalarMeta::new_new::<T, _>(T::type_name(info).to_owned())
|
ScalarMeta::new_new::<T, _>(T::type_name(info).to_owned())
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
/// Builds a [`ScalarMeta`] information for the [`?Sized`] specified
|
||||||
|
/// [`graphql::Type`].
|
||||||
|
///
|
||||||
|
/// [`graphql::Type`]: resolve::Type
|
||||||
|
pub fn build_scalar_type_unsized<T, Info>(&mut self, info: &Info) -> ScalarMeta<'r, S>
|
||||||
|
where
|
||||||
|
T: resolve::TypeName<Info> + resolve::ScalarToken<S> + resolve::InputValueAsRef<S> + ?Sized,
|
||||||
|
Info: ?Sized,
|
||||||
|
{
|
||||||
|
// TODO: Allow using references.
|
||||||
|
ScalarMeta::new_unsized::<T, _>(T::type_name(info).to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a [`ListMeta`] type.
|
/// Creates a [`ListMeta`] type.
|
||||||
///
|
///
|
||||||
|
|
|
@ -82,12 +82,12 @@ pub use crate::{
|
||||||
async_await::{GraphQLTypeAsync, GraphQLValueAsync},
|
async_await::{GraphQLTypeAsync, GraphQLValueAsync},
|
||||||
base::{Arguments, GraphQLType, GraphQLValue, TypeKind},
|
base::{Arguments, GraphQLType, GraphQLValue, TypeKind},
|
||||||
marker::{self, GraphQLInterface, GraphQLObject, GraphQLUnion},
|
marker::{self, GraphQLInterface, GraphQLObject, GraphQLUnion},
|
||||||
Nullable,
|
|
||||||
scalars::{EmptyMutation, EmptySubscription, ID},
|
scalars::{EmptyMutation, EmptySubscription, ID},
|
||||||
subscriptions::{
|
subscriptions::{
|
||||||
ExecutionOutput, GraphQLSubscriptionType, GraphQLSubscriptionValue,
|
ExecutionOutput, GraphQLSubscriptionType, GraphQLSubscriptionValue,
|
||||||
SubscriptionConnection, SubscriptionCoordinator,
|
SubscriptionConnection, SubscriptionCoordinator,
|
||||||
},
|
},
|
||||||
|
Nullable,
|
||||||
},
|
},
|
||||||
validation::RuleError,
|
validation::RuleError,
|
||||||
value::{DefaultScalarValue, Object, ParseScalarResult, ParseScalarValue, ScalarValue, Value},
|
value::{DefaultScalarValue, Object, ParseScalarResult, ParseScalarValue, ScalarValue, Value},
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graphql,
|
graphql,
|
||||||
meta::MetaType,
|
meta::MetaType,
|
||||||
parser::{self, ParseError},
|
parser::{self, ParseError},
|
||||||
Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, Registry, Selection,
|
Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, Registry,
|
||||||
|
Selection,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Type<Info: ?Sized, S = DefaultScalarValue> {
|
pub trait Type<Info: ?Sized, S = DefaultScalarValue> {
|
||||||
|
@ -84,7 +83,7 @@ pub trait ScalarToken<S = DefaultScalarValue> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InputValue<'input, S: 'input = DefaultScalarValue>: Sized {
|
pub trait InputValue<'input, S: 'input = DefaultScalarValue>: Sized {
|
||||||
type Error;
|
type Error: IntoFieldError<S>;
|
||||||
|
|
||||||
fn try_from_input_value(v: &'input graphql::InputValue<S>) -> Result<Self, Self::Error>;
|
fn try_from_input_value(v: &'input graphql::InputValue<S>) -> Result<Self, Self::Error>;
|
||||||
|
|
||||||
|
@ -98,13 +97,24 @@ pub trait InputValueOwned<S = DefaultScalarValue>: for<'i> InputValue<'i, S> {}
|
||||||
impl<T, S> InputValueOwned<S> for T where T: for<'i> InputValue<'i, S> {}
|
impl<T, S> InputValueOwned<S> for T where T: for<'i> InputValue<'i, S> {}
|
||||||
|
|
||||||
pub trait InputValueAsRef<S = DefaultScalarValue> {
|
pub trait InputValueAsRef<S = DefaultScalarValue> {
|
||||||
type Error;
|
type Error: IntoFieldError<S>;
|
||||||
|
|
||||||
fn try_from_input_value(v: &graphql::InputValue<S>) -> Result<&Self, Self::Error>;
|
fn try_from_input_value(v: &graphql::InputValue<S>) -> Result<&Self, Self::Error>;
|
||||||
|
|
||||||
fn try_from_implicit_null() -> Result<&'static Self, Self::Error>
|
fn try_from_implicit_null<'a>() -> Result<&'a Self, Self::Error>
|
||||||
where S: 'static
|
where
|
||||||
|
S: 'a,
|
||||||
{
|
{
|
||||||
Self::try_from_input_value(&graphql::InputValue::<S>::Null)
|
Self::try_from_input_value(&graphql::InputValue::<S>::Null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
impl<T, S> InputValueAsRef<S> for T where T: InputValueOwned<S> {
|
||||||
|
type Error = <T as InputValueOwned<S>>::Error;
|
||||||
|
|
||||||
|
fn try_from_input_value(v: &graphql::InputValue<S>) -> Result<&Self, Self::Error> {
|
||||||
|
<T as InputValueOwned<S>>::try_from_input_value(v).as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
borrow::{Cow, ToOwned},
|
borrow::{Cow, ToOwned},
|
||||||
convert::TryFrom,
|
|
||||||
fmt,
|
fmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -449,28 +448,42 @@ impl<'a, S> ScalarMeta<'a, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
/// Builds a new [`ScalarMeta`] information with the specified `name`.
|
/// Builds a new [`ScalarMeta`] information with the specified `name`.
|
||||||
// TODO: Use `impl Into<Cow<'a, str>>` argument once feature
|
// TODO: Use `impl Into<Cow<'a, str>>` argument once feature
|
||||||
// `explicit_generic_args_with_impl_trait` hits stable:
|
// `explicit_generic_args_with_impl_trait` hits stable:
|
||||||
// https://github.com/rust-lang/rust/issues/83701
|
// https://github.com/rust-lang/rust/issues/83701
|
||||||
pub fn new_new<T, N>(name: N) -> Self
|
pub fn new_new<T, N>(name: N) -> Self
|
||||||
where
|
where
|
||||||
T: resolve::ValidateInputValue<S> + resolve::ScalarToken<S>,
|
T: resolve::InputValueOwned<S> + resolve::ScalarToken<S>,
|
||||||
//T: for<'inp> resolve::InputValue<'inp, S> + resolve::ScalarToken<S>,
|
|
||||||
//for<'inp> <T as TryFrom<&'inp InputValue<S>>>::Error: IntoFieldError<S>,
|
|
||||||
Cow<'a, str>: From<N>,
|
Cow<'a, str>: From<N>,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
description: None,
|
description: None,
|
||||||
specified_by_url: None,
|
specified_by_url: None,
|
||||||
try_parse_fn: <T as resolve::ValidateInputValue<S>>::validate_input_value,
|
try_parse_fn: try_parse_fn_new::<S, T>,
|
||||||
//try_parse_fn: |inp| try_parse_fn_new::<S, T>(inp),
|
parse_fn: <T as resolve::ScalarToken<S>>::parse_scalar_token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds a new [`ScalarMeta`] information with the specified `name` for
|
||||||
|
/// the [`?Sized`] `T`ype that may only be parsed as a reference.
|
||||||
|
// TODO: Use `impl Into<Cow<'a, str>>` argument once feature
|
||||||
|
// `explicit_generic_args_with_impl_trait` hits stable:
|
||||||
|
// https://github.com/rust-lang/rust/issues/83701
|
||||||
|
pub fn new_unsized<T, N>(name: N) -> Self
|
||||||
|
where
|
||||||
|
T: resolve::InputValueAsRef<S> + resolve::ScalarToken<S> + ?Sized,
|
||||||
|
Cow<'a, str>: From<N>,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
description: None,
|
||||||
|
specified_by_url: None,
|
||||||
|
try_parse_fn: try_parse_unsized_fn::<S, T>,
|
||||||
parse_fn: <T as resolve::ScalarToken<S>>::parse_scalar_token,
|
parse_fn: <T as resolve::ScalarToken<S>>::parse_scalar_token,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/// Sets the `description` of this [`ScalarMeta`] type.
|
/// Sets the `description` of this [`ScalarMeta`] type.
|
||||||
///
|
///
|
||||||
|
@ -824,12 +837,20 @@ where
|
||||||
.map_err(T::Error::into_field_error)
|
.map_err(T::Error::into_field_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
fn try_parse_fn_new<S, T>(v: &InputValue<S>) -> Result<(), FieldError<S>>
|
||||||
fn try_parse_fn_new<'inp, 'b: 'inp, S: 'inp, T>(v: &'b InputValue<S>) -> Result<(), FieldError<S>>
|
|
||||||
where
|
where
|
||||||
T: resolve::InputValue<'inp, S>,
|
T: resolve::InputValueOwned<S>,
|
||||||
T::Error: IntoFieldError<S>,
|
|
||||||
{
|
{
|
||||||
T::try_from(v).map(drop).map_err(T::Error::into_field_error)
|
T::try_from_input_value(v)
|
||||||
|
.map(drop)
|
||||||
|
.map_err(T::Error::into_field_error)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_parse_unsized_fn<S, T>(v: &InputValue<S>) -> Result<(), FieldError<S>>
|
||||||
|
where
|
||||||
|
T: resolve::InputValueAsRef<S> + ?Sized,
|
||||||
|
{
|
||||||
|
T::try_from_input_value(v)
|
||||||
|
.map(drop)
|
||||||
|
.map_err(T::Error::into_field_error)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
@ -149,6 +149,22 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: how to parse unsized?
|
||||||
|
impl<'inp, T, S: 'inp> resolve::InputValue<'inp, S> for Box<T>
|
||||||
|
where
|
||||||
|
T: resolve::InputValue<'inp, S>,
|
||||||
|
{
|
||||||
|
type Error = <T as resolve::InputValue<'inp, S>>::Error;
|
||||||
|
|
||||||
|
fn try_from_input_value(v: &'inp graphql::InputValue<S>) -> Result<Self, Self::Error> {
|
||||||
|
<T as resolve::InputValue<'inp, S>>::try_from_input_value(v).map(Self::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_from_implicit_null() -> Result<Self, Self::Error> {
|
||||||
|
<T as resolve::InputValue<'inp, S>>::try_from_implicit_null().map(Self::new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> graphql::InputType<S> for Box<T>
|
impl<T, S> graphql::InputType<S> for Box<T>
|
||||||
where
|
where
|
||||||
T: graphql::InputType<S> + ?Sized,
|
T: graphql::InputType<S> + ?Sized,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod array;
|
|
||||||
mod arc;
|
mod arc;
|
||||||
|
mod array;
|
||||||
mod r#box;
|
mod r#box;
|
||||||
pub mod iter;
|
pub mod iter;
|
||||||
mod nullable;
|
mod nullable;
|
||||||
|
|
|
@ -324,6 +324,25 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'inp, T, S: 'inp> resolve::InputValue<'inp, S> for Nullable<T>
|
||||||
|
where
|
||||||
|
T: resolve::InputValue<'inp, S>,
|
||||||
|
{
|
||||||
|
type Error = <T as resolve::InputValue<'inp, S>>::Error;
|
||||||
|
|
||||||
|
fn try_from_input_value(v: &'inp InputValue<S>) -> Result<Self, Self::Error> {
|
||||||
|
if v.is_null() {
|
||||||
|
Ok(Self::ExplicitNull)
|
||||||
|
} else {
|
||||||
|
<T as resolve::InputValue<'inp, S>>::try_from_input_value(v).map(Self::Some)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_from_implicit_null() -> Result<Self, Self::Error> {
|
||||||
|
Ok(Self::ImplicitNull)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> graphql::InputType<S> for Nullable<T>
|
impl<T, S> graphql::InputType<S> for Nullable<T>
|
||||||
where
|
where
|
||||||
T: graphql::InputType<S>,
|
T: graphql::InputType<S>,
|
||||||
|
|
|
@ -61,6 +61,21 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'inp, T, S: 'inp> resolve::InputValue<'inp, S> for Option<T>
|
||||||
|
where
|
||||||
|
T: resolve::InputValue<'inp, S>,
|
||||||
|
{
|
||||||
|
type Error = <T as resolve::InputValue<'inp, S>>::Error;
|
||||||
|
|
||||||
|
fn try_from_input_value(v: &'inp graphql::InputValue<S>) -> Result<Self, Self::Error> {
|
||||||
|
if v.is_null() {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
<T as resolve::InputValue<'inp, S>>::try_from_input_value(v).map(Some)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> graphql::InputType<S> for Option<T>
|
impl<T, S> graphql::InputType<S> for Option<T>
|
||||||
where
|
where
|
||||||
T: graphql::InputType<S>,
|
T: graphql::InputType<S>,
|
||||||
|
|
|
@ -2,16 +2,13 @@
|
||||||
//!
|
//!
|
||||||
//! [`str`]: primitive@std::str
|
//! [`str`]: primitive@std::str
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
|
||||||
use futures::future;
|
use futures::future;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graphql,
|
graphql,
|
||||||
meta::MetaType,
|
meta::MetaType,
|
||||||
parser::{ParseError, ScalarToken},
|
parser::{ParseError, ScalarToken},
|
||||||
resolve, BoxFuture, ExecutionResult, Executor, IntoFieldError, Registry, ScalarValue,
|
resolve, BoxFuture, ExecutionResult, Executor, Registry, ScalarValue, Selection,
|
||||||
Selection,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<Info: ?Sized, S: ScalarValue> resolve::Type<Info, S> for str {
|
impl<Info: ?Sized, S: ScalarValue> resolve::Type<Info, S> for str {
|
||||||
|
@ -19,8 +16,9 @@ impl<Info: ?Sized, S: ScalarValue> resolve::Type<Info, S> for str {
|
||||||
where
|
where
|
||||||
S: 'r,
|
S: 'r,
|
||||||
{
|
{
|
||||||
// registry.build_scalar_type_new::<&Self, _>(info).into_meta()
|
registry
|
||||||
unimplemented!()
|
.build_scalar_type_unsized::<Self, _>(info)
|
||||||
|
.into_meta()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue