diff --git a/juniper/src/resolve/mod.rs b/juniper/src/resolve/mod.rs index 12e108d6..39c693e3 100644 --- a/juniper/src/resolve/mod.rs +++ b/juniper/src/resolve/mod.rs @@ -6,6 +6,12 @@ use crate::{ Selection, }; +#[doc(inline)] +pub use crate::types::{ + arc::TryFromInputValue as InputValueAsArc, r#box::TryFromInputValue as InputValueAsBox, + r#ref::TryFromInputValue as InputValueAsRef, rc::TryFromInputValue as InputValueAsRc, +}; + pub trait Type { fn meta<'r>(registry: &mut Registry<'r, S>, info: &Info) -> MetaType<'r, S> where @@ -95,26 +101,3 @@ pub trait InputValue<'input, S: 'input = DefaultScalarValue>: Sized { pub trait InputValueOwned: for<'i> InputValue<'i, S> {} impl InputValueOwned for T where T: for<'i> InputValue<'i, S> {} - -pub trait InputValueAsRef { - type Error: IntoFieldError; - - fn try_from_input_value(v: &graphql::InputValue) -> Result<&Self, Self::Error>; - - fn try_from_implicit_null<'a>() -> Result<&'a Self, Self::Error> - where - S: 'a, - { - Self::try_from_input_value(&graphql::InputValue::::Null) - } -} - -/* -impl InputValueAsRef for T where T: InputValueOwned { - type Error = >::Error; - - fn try_from_input_value(v: &graphql::InputValue) -> Result<&Self, Self::Error> { - >::try_from_input_value(v).as_ref() - } -} -*/ diff --git a/juniper/src/types/arc.rs b/juniper/src/types/arc.rs index 309022d5..6c9b8faf 100644 --- a/juniper/src/types/arc.rs +++ b/juniper/src/types/arc.rs @@ -6,7 +6,8 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection, + resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, + Registry, Selection, }; impl resolve::Type for Arc @@ -151,6 +152,48 @@ where } } +impl<'inp, T, S> resolve::InputValue<'inp, S> for Arc +where + T: resolve::InputValueAsArc<'inp, S> + ?Sized, + S: 'inp, +{ + type Error = >::Error; + + fn try_from_input_value(v: &'inp graphql::InputValue) -> Result { + >::try_from_input_value(v) + } + + fn try_from_implicit_null() -> Result { + >::try_from_implicit_null() + } +} + +pub trait TryFromInputValue<'input, S: 'input = DefaultScalarValue> { + type Error: IntoFieldError; + + fn try_from_input_value(v: &'input graphql::InputValue) -> Result, Self::Error>; + + fn try_from_implicit_null() -> Result, Self::Error> { + Self::try_from_input_value(&graphql::InputValue::::Null) + } +} + +impl<'inp, T, S> TryFromInputValue<'inp, S> for T +where + T: resolve::InputValue<'inp, S>, + S: 'inp, +{ + type Error = >::Error; + + fn try_from_input_value(v: &'inp graphql::InputValue) -> Result, Self::Error> { + >::try_from_input_value(v).map(Arc::new) + } + + fn try_from_implicit_null() -> Result, Self::Error> { + >::try_from_implicit_null().map(Arc::new) + } +} + impl graphql::InputType for Arc where T: graphql::InputType + ?Sized, diff --git a/juniper/src/types/box.rs b/juniper/src/types/box.rs index 3354d399..337d1540 100644 --- a/juniper/src/types/box.rs +++ b/juniper/src/types/box.rs @@ -4,7 +4,8 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection, + resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, + Registry, Selection, }; impl resolve::Type for Box @@ -149,19 +150,45 @@ where } } -// TODO: how to parse unsized? -impl<'inp, T, S: 'inp> resolve::InputValue<'inp, S> for Box +impl<'inp, T, S> resolve::InputValue<'inp, S> for Box where - T: resolve::InputValue<'inp, S>, + T: resolve::InputValueAsBox<'inp, S> + ?Sized, + S: 'inp, { - type Error = >::Error; + type Error = >::Error; fn try_from_input_value(v: &'inp graphql::InputValue) -> Result { - >::try_from_input_value(v).map(Self::new) + >::try_from_input_value(v) } fn try_from_implicit_null() -> Result { - >::try_from_implicit_null().map(Self::new) + >::try_from_implicit_null() + } +} + +pub trait TryFromInputValue<'input, S: 'input = DefaultScalarValue> { + type Error: IntoFieldError; + + fn try_from_input_value(v: &'input graphql::InputValue) -> Result, Self::Error>; + + fn try_from_implicit_null() -> Result, Self::Error> { + Self::try_from_input_value(&graphql::InputValue::::Null) + } +} + +impl<'inp, T, S> TryFromInputValue<'inp, S> for T +where + T: resolve::InputValue<'inp, S>, + S: 'inp, +{ + type Error = >::Error; + + fn try_from_input_value(v: &'inp graphql::InputValue) -> Result, Self::Error> { + >::try_from_input_value(v).map(Box::new) + } + + fn try_from_implicit_null() -> Result, Self::Error> { + >::try_from_implicit_null().map(Box::new) } } diff --git a/juniper/src/types/mod.rs b/juniper/src/types/mod.rs index 31517c72..58dfde7c 100644 --- a/juniper/src/types/mod.rs +++ b/juniper/src/types/mod.rs @@ -1,11 +1,11 @@ -mod arc; +pub mod arc; mod array; -mod r#box; +pub mod r#box; pub mod iter; mod nullable; mod option; -mod rc; -mod r#ref; +pub mod rc; +pub mod r#ref; mod ref_mut; mod slice; mod r#str; diff --git a/juniper/src/types/rc.rs b/juniper/src/types/rc.rs index 430790c9..8bae3053 100644 --- a/juniper/src/types/rc.rs +++ b/juniper/src/types/rc.rs @@ -6,7 +6,8 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection, + resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, + Registry, Selection, }; impl resolve::Type for Rc @@ -151,6 +152,48 @@ where } } +impl<'inp, T, S> resolve::InputValue<'inp, S> for Rc +where + T: resolve::InputValueAsRc<'inp, S> + ?Sized, + S: 'inp, +{ + type Error = >::Error; + + fn try_from_input_value(v: &'inp graphql::InputValue) -> Result { + >::try_from_input_value(v) + } + + fn try_from_implicit_null() -> Result { + >::try_from_implicit_null() + } +} + +pub trait TryFromInputValue<'input, S: 'input = DefaultScalarValue> { + type Error: IntoFieldError; + + fn try_from_input_value(v: &'input graphql::InputValue) -> Result, Self::Error>; + + fn try_from_implicit_null() -> Result, Self::Error> { + Self::try_from_input_value(&graphql::InputValue::::Null) + } +} + +impl<'inp, T, S> TryFromInputValue<'inp, S> for T +where + T: resolve::InputValue<'inp, S>, + S: 'inp, +{ + type Error = >::Error; + + fn try_from_input_value(v: &'inp graphql::InputValue) -> Result, Self::Error> { + >::try_from_input_value(v).map(Rc::new) + } + + fn try_from_implicit_null() -> Result, Self::Error> { + >::try_from_implicit_null().map(Rc::new) + } +} + impl graphql::InputType for Rc where T: graphql::InputType + ?Sized, diff --git a/juniper/src/types/ref.rs b/juniper/src/types/ref.rs index 78407fdb..83d33ac1 100644 --- a/juniper/src/types/ref.rs +++ b/juniper/src/types/ref.rs @@ -6,7 +6,8 @@ use crate::{ graphql, meta::MetaType, parser::{ParseError, ScalarToken}, - resolve, Arguments, BoxFuture, ExecutionResult, Executor, Registry, Selection, + resolve, Arguments, BoxFuture, DefaultScalarValue, ExecutionResult, Executor, IntoFieldError, + Registry, Selection, }; impl<'me, T, Info, S> resolve::Type for &'me T @@ -166,6 +167,19 @@ where } } +pub trait TryFromInputValue { + type Error: IntoFieldError; + + fn try_from_input_value(v: &graphql::InputValue) -> Result<&Self, Self::Error>; + + fn try_from_implicit_null<'a>() -> Result<&'a Self, Self::Error> + where + S: 'a, + { + Self::try_from_input_value(&graphql::InputValue::::Null) + } +} + impl<'me, T, S> graphql::InputType for &'me T where T: graphql::InputType + ?Sized, diff --git a/juniper/src/types/str.rs b/juniper/src/types/str.rs index b7eb4845..47b26a67 100644 --- a/juniper/src/types/str.rs +++ b/juniper/src/types/str.rs @@ -2,6 +2,8 @@ //! //! [`str`]: primitive@std::str +use std::{sync::Arc, rc::Rc}; + use futures::future; use crate::{ @@ -65,14 +67,14 @@ where } } -impl<'me, S: ScalarValue> resolve::ScalarToken for str { +impl resolve::ScalarToken for str { fn parse_scalar_token(token: ScalarToken<'_>) -> Result> { // TODO: Replace with `resolve::ScalarToken` >::from_str(token) } } -impl<'me, S: ScalarValue> resolve::InputValueAsRef for str { +impl resolve::InputValueAsRef for str { type Error = String; fn try_from_input_value(v: &graphql::InputValue) -> Result<&Self, Self::Error> { @@ -81,6 +83,30 @@ impl<'me, S: ScalarValue> resolve::InputValueAsRef for str { } } +impl<'inp, S: ScalarValue> resolve::InputValueAsBox<'inp, S> for str { + type Error = String; + + fn try_from_input_value(v: &'inp graphql::InputValue) -> Result, Self::Error> { + >::try_from_input_value(v).map(Into::into) + } +} + +impl<'inp, S: ScalarValue> resolve::InputValueAsArc<'inp, S> for str { + type Error = String; + + fn try_from_input_value(v: &'inp graphql::InputValue) -> Result, Self::Error> { + >::try_from_input_value(v).map(Into::into) + } +} + +impl<'inp, S: ScalarValue> resolve::InputValueAsRc<'inp, S> for str { + type Error = String; + + fn try_from_input_value(v: &'inp graphql::InputValue) -> Result, Self::Error> { + >::try_from_input_value(v).map(Into::into) + } +} + impl graphql::InputType for str { fn assert_input_type() {} }