Impl basic types, vol.3
This commit is contained in:
parent
c8759cd16e
commit
64cf7adb4f
11 changed files with 318 additions and 26 deletions
|
@ -4,6 +4,7 @@ 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},
|
||||||
};
|
};
|
||||||
|
@ -1294,6 +1295,21 @@ 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`].
|
||||||
|
///
|
||||||
|
/// [`graphql::Type`]: resolve::Type
|
||||||
|
pub fn build_scalar_type_new<'info, T, Info>(&mut self, info: &Info) -> ScalarMeta<'r, S>
|
||||||
|
where
|
||||||
|
T: resolve::TypeName<Info>
|
||||||
|
+ resolve::ScalarToken<S>
|
||||||
|
+ for<'inp> resolve::InputValue<'inp, S>,
|
||||||
|
for<'i> <T as TryFrom<&'i InputValue<S>>>::Error: IntoFieldError<S>,
|
||||||
|
Info: ?Sized,
|
||||||
|
{
|
||||||
|
// TODO: Allow using references.
|
||||||
|
ScalarMeta::new_new::<T, _>(T::type_name(info).to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a [`ListMeta`] type.
|
/// Creates a [`ListMeta`] type.
|
||||||
///
|
///
|
||||||
/// Specifying `expected_size` will be used to ensure that values of this
|
/// Specifying `expected_size` will be used to ensure that values of this
|
||||||
|
|
|
@ -2,7 +2,9 @@ pub mod resolve;
|
||||||
|
|
||||||
use crate::DefaultScalarValue;
|
use crate::DefaultScalarValue;
|
||||||
|
|
||||||
pub use crate::value::Value;
|
pub use crate::{
|
||||||
|
ast::InputValue, graphql_input_value as input_value, graphql_value as value, value::Value,
|
||||||
|
};
|
||||||
|
|
||||||
pub use self::resolve::Type;
|
pub use self::resolve::Type;
|
||||||
|
|
||||||
|
@ -34,6 +36,17 @@ pub trait Object<S = DefaultScalarValue>:
|
||||||
fn assert_object();
|
fn assert_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Scalar<S = DefaultScalarValue>:
|
||||||
|
InputType<S>
|
||||||
|
+ OutputType<S>
|
||||||
|
+ Type<S>
|
||||||
|
+ resolve::TypeName
|
||||||
|
+ resolve::Value<S>
|
||||||
|
+ resolve::ValueAsync<S>
|
||||||
|
{
|
||||||
|
fn assert_scalar();
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Union<S = DefaultScalarValue>:
|
pub trait Union<S = DefaultScalarValue>:
|
||||||
OutputType<S>
|
OutputType<S>
|
||||||
+ Type<S>
|
+ Type<S>
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
meta::MetaType, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, Registry,
|
graphql,
|
||||||
Selection,
|
meta::MetaType,
|
||||||
|
parser::{self, ParseError},
|
||||||
|
Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, Registry, Selection,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Type<Info: ?Sized, S = DefaultScalarValue> {
|
pub trait Type<Info: ?Sized, S = DefaultScalarValue> {
|
||||||
fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S>
|
fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S>
|
||||||
where
|
where
|
||||||
S: 'r;
|
S: 'r; // TODO: remove?
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TypeName<Info: ?Sized> {
|
pub trait TypeName<Info: ?Sized> {
|
||||||
|
@ -74,3 +78,40 @@ pub trait FieldAsync<Info: ?Sized, Ctx: ?Sized, S = DefaultScalarValue> {
|
||||||
executor: &'r Executor<Ctx, S>,
|
executor: &'r Executor<Ctx, S>,
|
||||||
) -> BoxFuture<'r, ExecutionResult<S>>;
|
) -> BoxFuture<'r, ExecutionResult<S>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait InputValue<'inp, S: 'inp>: TryFrom<&'inp graphql::InputValue<S>> {
|
||||||
|
fn try_from_implicit_null() -> Result<Self, Self::Error> {
|
||||||
|
Self::try_from(&graphql::InputValue::<S>::Null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait InputValueOwned<S>: for<'inp> InputValue<'inp, S> {}
|
||||||
|
|
||||||
|
impl<T, S> InputValueOwned<S> for T where T: for<'inp> InputValue<'inp, S> {}
|
||||||
|
|
||||||
|
pub trait ValidateInputValue<S>: Sized {
|
||||||
|
fn validate_input_value<'inp>(
|
||||||
|
v: &'inp graphql::InputValue<S>,
|
||||||
|
) -> Result<(), crate::FieldError<S>>
|
||||||
|
where
|
||||||
|
Self: TryFrom<&'inp graphql::InputValue<S>>,
|
||||||
|
<Self as TryFrom<&'inp graphql::InputValue<S>>>::Error: crate::IntoFieldError<S>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S> ValidateInputValue<S> for T {
|
||||||
|
fn validate_input_value<'inp>(
|
||||||
|
v: &'inp graphql::InputValue<S>,
|
||||||
|
) -> Result<(), crate::FieldError<S>>
|
||||||
|
where
|
||||||
|
Self: TryFrom<&'inp graphql::InputValue<S>>,
|
||||||
|
<Self as TryFrom<&'inp graphql::InputValue<S>>>::Error: crate::IntoFieldError<S>,
|
||||||
|
{
|
||||||
|
Self::try_from(v)
|
||||||
|
.map(drop)
|
||||||
|
.map_err(crate::IntoFieldError::<S>::into_field_error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ScalarToken<S = DefaultScalarValue> {
|
||||||
|
fn parse_scalar_token(token: parser::ScalarToken<'_>) -> Result<S, ParseError<'_>>;
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
//! Types used to describe a `GraphQL` schema
|
//! Types used to describe a `GraphQL` schema
|
||||||
|
|
||||||
use juniper::IntoFieldError;
|
|
||||||
use std::{
|
use std::{
|
||||||
borrow::{Cow, ToOwned},
|
borrow::{Cow, ToOwned},
|
||||||
|
convert::TryFrom,
|
||||||
fmt,
|
fmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{FromInputValue, InputValue, Type},
|
ast::{FromInputValue, InputValue, Type},
|
||||||
parser::{ParseError, ScalarToken},
|
parser::{ParseError, ScalarToken},
|
||||||
|
resolve,
|
||||||
schema::model::SchemaType,
|
schema::model::SchemaType,
|
||||||
types::base::TypeKind,
|
types::base::TypeKind,
|
||||||
value::{DefaultScalarValue, ParseScalarValue},
|
value::{DefaultScalarValue, ParseScalarValue},
|
||||||
FieldError,
|
FieldError, IntoFieldError,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Whether an item is deprecated, with context.
|
/// Whether an item is deprecated, with context.
|
||||||
|
@ -28,16 +29,16 @@ impl DeprecationStatus {
|
||||||
/// If this deprecation status indicates the item is deprecated.
|
/// If this deprecation status indicates the item is deprecated.
|
||||||
pub fn is_deprecated(&self) -> bool {
|
pub fn is_deprecated(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
DeprecationStatus::Current => false,
|
Self::Current => false,
|
||||||
DeprecationStatus::Deprecated(_) => true,
|
Self::Deprecated(_) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An optional reason for the deprecation, or none if `Current`.
|
/// An optional reason for the deprecation, or none if `Current`.
|
||||||
pub fn reason(&self) -> Option<&str> {
|
pub fn reason(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
DeprecationStatus::Current => None,
|
Self::Current => None,
|
||||||
DeprecationStatus::Deprecated(rsn) => rsn.as_deref(),
|
Self::Deprecated(rsn) => rsn.as_deref(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,6 +449,27 @@ impl<'a, S> ScalarMeta<'a, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Builds a new [`ScalarMeta`] information with the specified `name`.
|
||||||
|
// 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_new<T, N>(name: N) -> Self
|
||||||
|
where
|
||||||
|
T: resolve::ValidateInputValue<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>,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
name: name.into(),
|
||||||
|
description: None,
|
||||||
|
specified_by_url: None,
|
||||||
|
try_parse_fn: <T as resolve::ValidateInputValue<S>>::validate_input_value,
|
||||||
|
//try_parse_fn: |inp| try_parse_fn_new::<S, T>(inp),
|
||||||
|
parse_fn: <T as resolve::ScalarToken<S>>::parse_scalar_token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the `description` of this [`ScalarMeta`] type.
|
/// Sets the `description` of this [`ScalarMeta`] type.
|
||||||
///
|
///
|
||||||
/// Overwrites any previously set description.
|
/// Overwrites any previously set description.
|
||||||
|
@ -799,3 +821,11 @@ where
|
||||||
.map(drop)
|
.map(drop)
|
||||||
.map_err(T::Error::into_field_error)
|
.map_err(T::Error::into_field_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_parse_fn_new<'inp, 'b: 'inp, S: 'inp, T>(v: &'b InputValue<S>) -> Result<(), FieldError<S>>
|
||||||
|
where
|
||||||
|
T: resolve::InputValue<'inp, S>,
|
||||||
|
T::Error: IntoFieldError<S>,
|
||||||
|
{
|
||||||
|
T::try_from(v).map(drop).map_err(T::Error::into_field_error)
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
executor::{ExecutionResult, Executor, Registry},
|
graphql,
|
||||||
graphql, resolve,
|
meta::MetaType,
|
||||||
schema::meta::MetaType,
|
parser::{ParseError, ScalarToken},
|
||||||
Arguments, BoxFuture, Selection,
|
resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<T, Info, S> resolve::Type<Info, S> for Arc<T>
|
impl<T, Info, S> resolve::Type<Info, S> for Arc<T>
|
||||||
|
@ -142,6 +142,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, S> resolve::ScalarToken<S> for Arc<T>
|
||||||
|
where
|
||||||
|
T: resolve::ScalarToken<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn parse_scalar_token(token: ScalarToken<'_>) -> Result<S, ParseError<'_>> {
|
||||||
|
T::parse_scalar_token(token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> graphql::InputType<S> for Arc<T>
|
impl<T, S> graphql::InputType<S> for Arc<T>
|
||||||
where
|
where
|
||||||
T: graphql::InputType<S> + ?Sized,
|
T: graphql::InputType<S> + ?Sized,
|
||||||
|
@ -178,6 +187,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, S> graphql::Scalar<S> for Arc<T>
|
||||||
|
where
|
||||||
|
T: graphql::Scalar<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn assert_scalar() {
|
||||||
|
T::assert_scalar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> graphql::Union<S> for Arc<T>
|
impl<T, S> graphql::Union<S> for Arc<T>
|
||||||
where
|
where
|
||||||
T: graphql::Union<S> + ?Sized,
|
T: graphql::Union<S> + ?Sized,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//! GraphQL implementation for [`Box`].
|
//! GraphQL implementation for [`Box`].
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
executor::{ExecutionResult, Executor, Registry},
|
graphql,
|
||||||
graphql, resolve,
|
meta::MetaType,
|
||||||
schema::meta::MetaType,
|
parser::{ParseError, ScalarToken},
|
||||||
Arguments, BoxFuture, Selection,
|
resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<T, Info, S> resolve::Type<Info, S> for Box<T>
|
impl<T, Info, S> resolve::Type<Info, S> for Box<T>
|
||||||
|
@ -140,6 +140,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, S> resolve::ScalarToken<S> for Box<T>
|
||||||
|
where
|
||||||
|
T: resolve::ScalarToken<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn parse_scalar_token(token: ScalarToken<'_>) -> Result<S, ParseError<'_>> {
|
||||||
|
T::parse_scalar_token(token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
@ -176,6 +185,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, S> graphql::Scalar<S> for Box<T>
|
||||||
|
where
|
||||||
|
T: graphql::Scalar<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn assert_scalar() {
|
||||||
|
T::assert_scalar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> graphql::Union<S> for Box<T>
|
impl<T, S> graphql::Union<S> for Box<T>
|
||||||
where
|
where
|
||||||
T: graphql::Union<S> + ?Sized,
|
T: graphql::Union<S> + ?Sized,
|
||||||
|
|
|
@ -8,6 +8,7 @@ mod rc;
|
||||||
mod r#ref;
|
mod r#ref;
|
||||||
mod ref_mut;
|
mod ref_mut;
|
||||||
mod slice;
|
mod slice;
|
||||||
|
mod r#str;
|
||||||
mod vec;
|
mod vec;
|
||||||
|
|
||||||
pub mod async_await;
|
pub mod async_await;
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
executor::{ExecutionResult, Executor, Registry},
|
graphql,
|
||||||
graphql, resolve,
|
meta::MetaType,
|
||||||
schema::meta::MetaType,
|
parser::{ParseError, ScalarToken},
|
||||||
Arguments, BoxFuture, Selection,
|
resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<T, Info, S> resolve::Type<Info, S> for Rc<T>
|
impl<T, Info, S> resolve::Type<Info, S> for Rc<T>
|
||||||
|
@ -142,6 +142,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, S> resolve::ScalarToken<S> for Rc<T>
|
||||||
|
where
|
||||||
|
T: resolve::ScalarToken<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn parse_scalar_token(token: ScalarToken<'_>) -> Result<S, ParseError<'_>> {
|
||||||
|
T::parse_scalar_token(token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> graphql::InputType<S> for Rc<T>
|
impl<T, S> graphql::InputType<S> for Rc<T>
|
||||||
where
|
where
|
||||||
T: graphql::InputType<S> + ?Sized,
|
T: graphql::InputType<S> + ?Sized,
|
||||||
|
@ -178,6 +187,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, S> graphql::Scalar<S> for Rc<T>
|
||||||
|
where
|
||||||
|
T: graphql::Scalar<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn assert_scalar() {
|
||||||
|
T::assert_scalar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, S> graphql::Union<S> for Rc<T>
|
impl<T, S> graphql::Union<S> for Rc<T>
|
||||||
where
|
where
|
||||||
T: graphql::Union<S> + ?Sized,
|
T: graphql::Union<S> + ?Sized,
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
//! [reference]: primitive@std::reference
|
//! [reference]: primitive@std::reference
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graphql, meta::MetaType, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry,
|
graphql,
|
||||||
Selection,
|
meta::MetaType,
|
||||||
|
parser::{ParseError, ScalarToken},
|
||||||
|
resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'me, T, Info, S> resolve::Type<Info, S> for &'me T
|
impl<'me, T, Info, S> resolve::Type<Info, S> for &'me T
|
||||||
|
@ -140,6 +142,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'me, T, S> resolve::ScalarToken<S> for &'me T
|
||||||
|
where
|
||||||
|
T: resolve::ScalarToken<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn parse_scalar_token(token: ScalarToken<'_>) -> Result<S, ParseError<'_>> {
|
||||||
|
T::parse_scalar_token(token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'me, T, S> graphql::InputType<S> for &'me T
|
impl<'me, T, S> graphql::InputType<S> for &'me T
|
||||||
where
|
where
|
||||||
T: graphql::InputType<S> + ?Sized,
|
T: graphql::InputType<S> + ?Sized,
|
||||||
|
@ -176,6 +187,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'me, T, S> graphql::Scalar<S> for &'me T
|
||||||
|
where
|
||||||
|
T: graphql::Scalar<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn assert_scalar() {
|
||||||
|
T::assert_scalar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'me, T, S> graphql::Union<S> for &'me T
|
impl<'me, T, S> graphql::Union<S> for &'me T
|
||||||
where
|
where
|
||||||
T: graphql::Union<S> + ?Sized,
|
T: graphql::Union<S> + ?Sized,
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
//! [reference]: primitive@std::reference
|
//! [reference]: primitive@std::reference
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graphql, meta::MetaType, resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry,
|
graphql,
|
||||||
Selection,
|
meta::MetaType,
|
||||||
|
parser::{ParseError, ScalarToken},
|
||||||
|
resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'me, T, Info, S> resolve::Type<Info, S> for &'me mut T
|
impl<'me, T, Info, S> resolve::Type<Info, S> for &'me mut T
|
||||||
|
@ -140,6 +142,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'me, T, S> resolve::ScalarToken<S> for &'me mut T
|
||||||
|
where
|
||||||
|
T: resolve::ScalarToken<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn parse_scalar_token(token: ScalarToken<'_>) -> Result<S, ParseError<'_>> {
|
||||||
|
T::parse_scalar_token(token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'me, T, S> graphql::InputType<S> for &'me mut T
|
impl<'me, T, S> graphql::InputType<S> for &'me mut T
|
||||||
where
|
where
|
||||||
T: graphql::InputType<S> + ?Sized,
|
T: graphql::InputType<S> + ?Sized,
|
||||||
|
@ -176,6 +187,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'me, T, S> graphql::Scalar<S> for &'me mut T
|
||||||
|
where
|
||||||
|
T: graphql::Scalar<S> + ?Sized,
|
||||||
|
{
|
||||||
|
fn assert_scalar() {
|
||||||
|
T::assert_scalar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'me, T, S> graphql::Union<S> for &'me mut T
|
impl<'me, T, S> graphql::Union<S> for &'me mut T
|
||||||
where
|
where
|
||||||
T: graphql::Union<S> + ?Sized,
|
T: graphql::Union<S> + ?Sized,
|
||||||
|
|
97
juniper/src/types/str.rs
Normal file
97
juniper/src/types/str.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
//! GraphQL implementation for [`str`].
|
||||||
|
//!
|
||||||
|
//! [`str`]: primitive@std::str
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
use futures::future;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
graphql,
|
||||||
|
meta::MetaType,
|
||||||
|
parser::{ParseError, ScalarToken},
|
||||||
|
resolve, BoxFuture, ExecutionResult, Executor, IntoFieldError, Registry, ScalarValue,
|
||||||
|
Selection,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<Info: ?Sized, S: ScalarValue> resolve::Type<Info, S> for str {
|
||||||
|
fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S>
|
||||||
|
where
|
||||||
|
S: 'r,
|
||||||
|
{
|
||||||
|
registry.build_scalar_type_new::<&Self, _>(info).into_meta()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Info: ?Sized> resolve::TypeName<Info> for str {
|
||||||
|
fn type_name(_: &Info) -> &'static str {
|
||||||
|
// TODO: Reuse from `String`.
|
||||||
|
"String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Info, Ctx, S> resolve::Value<Info, Ctx, S> for str
|
||||||
|
where
|
||||||
|
Info: ?Sized,
|
||||||
|
Ctx: ?Sized,
|
||||||
|
S: From<String>,
|
||||||
|
{
|
||||||
|
fn resolve_value(
|
||||||
|
&self,
|
||||||
|
_: Option<&[Selection<'_, S>]>,
|
||||||
|
_: &Info,
|
||||||
|
_: &Executor<Ctx, S>,
|
||||||
|
) -> ExecutionResult<S> {
|
||||||
|
// TODO: Remove redundant `.to_owned()` allocation by allowing
|
||||||
|
// `ScalarValue` creation from reference?
|
||||||
|
Ok(graphql::Value::scalar(self.to_owned()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Info, Ctx, S> resolve::ValueAsync<Info, Ctx, S> for str
|
||||||
|
where
|
||||||
|
Info: ?Sized,
|
||||||
|
Ctx: ?Sized,
|
||||||
|
S: From<String> + Send,
|
||||||
|
{
|
||||||
|
fn resolve_value_async<'r>(
|
||||||
|
&'r self,
|
||||||
|
_: Option<&'r [Selection<'_, S>]>,
|
||||||
|
_: &'r Info,
|
||||||
|
_: &'r Executor<Ctx, S>,
|
||||||
|
) -> BoxFuture<'r, ExecutionResult<S>> {
|
||||||
|
// TODO: Remove redundant `.to_owned()` allocation by allowing
|
||||||
|
// `ScalarValue` creation from reference?
|
||||||
|
Box::pin(future::ok(graphql::Value::scalar(self.to_owned())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'me, S: ScalarValue> resolve::ScalarToken<S> for str {
|
||||||
|
fn parse_scalar_token(token: ScalarToken<'_>) -> Result<S, ParseError<'_>> {
|
||||||
|
// TODO: replace with `resolve::ScalarToken<S>`
|
||||||
|
<String as crate::ParseScalarValue<S>>::from_str(token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> graphql::InputType<S> for str {
|
||||||
|
fn assert_input_type() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> graphql::OutputType<S> for str {
|
||||||
|
fn assert_output_type() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> graphql::Scalar<S> for str {
|
||||||
|
fn assert_scalar() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'inp: 'me, 'me, S: ScalarValue> TryFrom<&'inp graphql::InputValue<S>> for &'me str {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
fn try_from(v: &'inp graphql::InputValue<S>) -> Result<Self, Self::Error> {
|
||||||
|
v.as_string_value()
|
||||||
|
.ok_or_else(|| format!("Expected `String`, found: {}", v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'inp: 'me, 'me, S: ScalarValue> resolve::InputValue<'inp, S> for &'me str {}
|
Loading…
Reference in a new issue