Refactor input_value! macro position [skip ci]

This commit is contained in:
tyranron 2022-06-07 18:53:01 +02:00
parent 97c88d219c
commit b716a45215
No known key found for this signature in database
GPG key ID: 762E144FB230A4F0
4 changed files with 213 additions and 195 deletions
juniper/src

View file

@ -1,67 +1,88 @@
use crate::{behavior, resolve};
pub use crate::{ pub use crate::{
ast::InputValue, graphql_input_value as input_value, graphql_value as value, value::Value, ast::InputValue, graphql_value as value, macros::input_value,
resolve::Type, value::Value,
}; };
pub trait Interface<S>: pub trait Interface<S>
OutputType<S> /*: OutputType<S>
/* + resolve::TypeName
+ resolve::TypeName + resolve::ConcreteTypeName
+ resolve::ConcreteTypeName + resolve::Value<S>
+ resolve::Value<S> + resolve::ValueAsync<S>
+ resolve::ValueAsync<S> + resolve::ConcreteValue<S>
+ resolve::ConcreteValue<S> + resolve::ConcreteValueAsync<S>
+ resolve::ConcreteValueAsync<S> + resolve::Field<S>
+ resolve::Field<S> + resolve::FieldAsync<S>
+ resolve::FieldAsync<S>
*/ */
{ {
fn assert_interface(); fn assert_interface();
} }
pub trait Object<S>: pub trait Object<S>
OutputType<S> /*: OutputType<S>
/* + resolve::TypeName
+ resolve::TypeName + resolve::ConcreteTypeName
+ resolve::ConcreteTypeName + resolve::Value<S>
+ resolve::Value<S> + resolve::ValueAsync<S>
+ resolve::ValueAsync<S> + resolve::Field<S>
+ resolve::Field<S> + resolve::FieldAsync<S>
+ resolve::FieldAsync<S>
*/ */
{ {
fn assert_object(); fn assert_object();
} }
pub trait Scalar<S>: pub trait Scalar<
OutputType<S> + /* 'inp,
resolve::TypeName + resolve::Value<S> + resolve::ValueAsync<S> */ TypeInfo: ?Sized,
Context: ?Sized,
ScalarValue: 'inp,
Behavior: ?Sized = behavior::Standard,
>:
InputType<'inp, TypeInfo, ScalarValue, Behavior>
+ OutputType<TypeInfo, Context, ScalarValue, Behavior>
+ resolve::ScalarToken<ScalarValue, Behavior>
{ {
fn assert_scalar(); fn assert_scalar();
} }
pub trait Union<S>: pub trait Union<S>
OutputType<S> /*: OutputType<S>
/* + resolve::TypeName
+ resolve::TypeName + resolve::ConcreteTypeName
+ resolve::ConcreteTypeName + resolve::Value<S>
+ resolve::Value<S> + resolve::ValueAsync<S>
+ resolve::ValueAsync<S> + resolve::ConcreteValue<S>
+ resolve::ConcreteValue<S> + resolve::ConcreteValueAsync<S> */
+ resolve::ConcreteValueAsync<S> */
{ {
fn assert_union(); fn assert_union();
} }
pub trait InputType<'inp, Info: ?Sized, S: 'inp> /*: pub trait InputType<
crate::resolve::Type<Info, S> 'inp,
+ crate::resolve::ToInputValue<S> TypeInfo: ?Sized,
+ crate::resolve::InputValue<'inp, S>*/ ScalarValue: 'inp,
Behavior: ?Sized = behavior::Standard,
>:
Type<TypeInfo, ScalarValue, Behavior>
+ resolve::ToInputValue<ScalarValue, Behavior>
+ resolve::InputValue<'inp, ScalarValue, Behavior>
{ {
fn assert_input_type(); fn assert_input_type();
} }
pub trait OutputType<S>: /*Type<S>*/ { pub trait OutputType<
TypeInfo: ?Sized,
Context: ?Sized,
ScalarValue,
Behavior: ?Sized = behavior::Standard,
>:
Type<TypeInfo, ScalarValue, Behavior>
+ resolve::Value<TypeInfo, Context, ScalarValue, Behavior>
+ resolve::ValueAsync<TypeInfo, Context, ScalarValue, Behavior>
{
fn assert_output_type(); fn assert_output_type();
} }

View file

@ -74,7 +74,10 @@ pub use crate::{
LookAheadSelection, LookAheadValue, OwnedExecutor, Registry, ValuesStream, Variables, LookAheadSelection, LookAheadValue, OwnedExecutor, Registry, ValuesStream, Variables,
}, },
introspection::IntrospectionFormat, introspection::IntrospectionFormat,
macros::helper::subscription::{ExtractTypeFromStream, IntoFieldResult}, macros::{
input_value as graphql_input_value,
helper::subscription::{ExtractTypeFromStream, IntoFieldResult},
},
parser::{ParseError, ScalarToken, Spanning}, parser::{ParseError, ScalarToken, Spanning},
schema::{ schema::{
meta, meta,

View file

@ -1,45 +1,43 @@
//! [`graphql_input_value!`] macro implementation. //! [`input_value!`] macro implementation.
//!
//! [`graphql_input_value!`]: graphql_input_value
/// Constructs [`InputValue`]s via JSON-like syntax. /// Constructs [`graphql::InputValue`]s via JSON-like syntax.
/// ///
/// # Differences from [`graphql_value!`] /// # Differences from [`graphql_value!`]
/// ///
/// - [`InputValue::Enum`] is constructed with `ident`, so to capture outer /// - [`InputValue::Enum`] is constructed with `ident`, so to capture outer
/// variable as [`InputValue::Scalar`] surround it with parens: `(var)`. /// variable as [`InputValue::Scalar`] surround it with parens: `(var)`.
/// ```rust /// ```rust
/// # use juniper::{graphql_input_value, graphql_value}; /// # use juniper::{graphql, graphql_value};
/// # /// #
/// # type InputValue = juniper::InputValue; /// # type InputValue = graphql::InputValue;
/// # type Value = juniper::Value; /// # type Value = graphql::Value;
/// # /// #
/// const OUTER_VAR: i32 = 42; /// const OUTER_VAR: i32 = 42;
/// assert_eq!(graphql_value!(OUTER_VAR), Value::scalar(42)); /// assert_eq!(graphql::value!(OUTER_VAR), Value::scalar(42));
/// assert_eq!(graphql_input_value!(OUTER_VAR), InputValue::enum_value("OUTER_VAR")); /// assert_eq!(graphql::input_value!(OUTER_VAR), InputValue::enum_value("OUTER_VAR"));
/// assert_eq!(graphql_input_value!((OUTER_VAR)), InputValue::scalar(42)); /// assert_eq!(graphql::input_value!((OUTER_VAR)), InputValue::scalar(42));
/// ``` /// ```
/// ///
/// - [`InputValue::Variable`] is constructed by prefixing `ident` with `@`. /// - [`InputValue::Variable`] is constructed by prefixing `ident` with `@`.
/// ```rust /// ```rust
/// # use juniper::graphql_input_value; /// # use juniper::graphql;
/// # /// #
/// # type InputValue = juniper::InputValue; /// # type InputValue = graphql::InputValue;
/// # /// #
/// assert_eq!(graphql_input_value!(@var), InputValue::variable("var")); /// assert_eq!(graphql::input_value!(@var), InputValue::variable("var"));
/// ``` /// ```
/// ///
/// - [`InputValue::Object`] key should implement [`Into`]`<`[`String`]`>`. /// - [`InputValue::Object`] key should implement [`Into`]`<`[`String`]`>`.
/// ```rust /// ```rust
/// # use std::borrow::Cow; /// # use std::borrow::Cow;
/// # /// #
/// # use juniper::{graphql_input_value, InputValue}; /// # use juniper::graphql;
/// # /// #
/// let code = 200; /// let code = 200;
/// let features = vec!["key", "value"]; /// let features = vec!["key", "value"];
/// let key: Cow<'static, str> = "key".into(); /// let key: Cow<'static, str> = "key".into();
/// ///
/// let value: InputValue = graphql_input_value!({ /// let value: graphql::InputValue = graphql::input_value!({
/// "code": code, /// "code": code,
/// "success": code == 200, /// "success": code == 200,
/// "payload": { /// "payload": {
@ -55,128 +53,127 @@
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # use juniper::{graphql_input_value, InputValue}; /// # use juniper::graphql;
/// # /// #
/// # type V = InputValue; /// # type V = graphql::InputValue;
/// # /// #
/// # let _: V = /// # let _: V =
/// graphql_input_value!(null); /// graphql::input_value!(null);
/// # let _: V = /// # let _: V =
/// graphql_input_value!(1234); /// graphql::input_value!(1234);
/// # let _: V = /// # let _: V =
/// graphql_input_value!("test"); /// graphql::input_value!("test");
/// # let _: V = /// # let _: V =
/// graphql_input_value!([1234, "test", true]); /// graphql::input_value!([1234, "test", true]);
/// # let _: V = /// # let _: V =
/// graphql_input_value!({"key": "value", "foo": 1234}); /// graphql::input_value!({"key": "value", "foo": 1234});
/// # let _: V = /// # let _: V =
/// graphql_input_value!({"key": ENUM}); /// graphql::input_value!({"key": ENUM});
/// let captured_var = 42; /// let captured_var = 42;
/// # let _: V = /// # let _: V =
/// graphql_input_value!({"key": (captured_var)}); /// graphql::input_value!({"key": (captured_var)});
/// # let _: V = /// # let _: V =
/// graphql_input_value!({"key": @variable}); /// graphql::input_value!({"key": @variable});
/// ``` /// ```
/// ///
/// [`InputValue`]: crate::InputValue /// [`graphql::InputValue`]: crate::graphql::InputValue
/// [`InputValue::Enum`]: crate::InputValue::Enum /// [`InputValue::Enum`]: crate::graphql::InputValue::Enum
/// [`InputValue::List`]: crate::InputValue::List /// [`InputValue::List`]: crate::graphql::InputValue::List
/// [`InputValue::Object`]: crate::InputValue::Object /// [`InputValue::Object`]: crate::graphql::InputValue::Object
/// [`InputValue::Scalar`]: crate::InputValue::Scalar /// [`InputValue::Scalar`]: crate::graphql::InputValue::Scalar
/// [`InputValue::Variable`]: crate::InputValue::Variable /// [`InputValue::Variable`]: crate::graphql::InputValue::Variable
/// [`Spanning::unlocated`]: crate::Spanning::unlocated /// [`Spanning::unlocated`]: crate::Spanning::unlocated
#[macro_export] macro_rules! input_value {
macro_rules! graphql_input_value {
/////////// ///////////
// Array // // Array //
/////////// ///////////
// Done with trailing comma. // Done with trailing comma.
(@@array [$($elems:expr,)*]) => { (@@array [$($elems:expr,)*]) => {
$crate::InputValue::list(vec![ $crate::graphql::InputValue::list(::std::vec![
$( $elems, )* $( $elems, )*
]) ])
}; };
// Done without trailing comma. // Done without trailing comma.
(@@array [$($elems:expr),*]) => { (@@array [$($elems:expr),*]) => {
$crate::InputValue::list(vec![ $crate::graphql::InputValue::list(::std::vec![
$( $elems, )* $( $elems, )*
]) ])
}; };
// Next element is `null`. // Next element is `null`.
(@@array [$($elems:expr,)*] null $($rest:tt)*) => { (@@array [$($elems:expr,)*] null $($rest:tt)*) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!(null)] $($rest)* @@array [$($elems,)* $crate::graphql::input_value!(null)] $($rest)*
) )
}; };
// Next element is `None`. // Next element is `None`.
(@@array [$($elems:expr,)*] None $($rest:tt)*) => { (@@array [$($elems:expr,)*] None $($rest:tt)*) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!(None)] $($rest)* @@array [$($elems,)* $crate::graphql::input_value!(None)] $($rest)*
) )
}; };
// Next element is a variable. // Next element is a variable.
(@@array [$($elems:expr,)*] @$var:ident $($rest:tt)*) => { (@@array [$($elems:expr,)*] @$var:ident $($rest:tt)*) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!(@$var)] $($rest)* @@array [$($elems,)* $crate::graphql::input_value!(@$var)] $($rest)*
) )
}; };
// Next element is an array. // Next element is an array.
(@@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { (@@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!([$($array)*])] $($rest)* @@array [$($elems,)* $crate::graphql::input_value!([$($array)*])] $($rest)*
) )
}; };
// Next element is a map. // Next element is a map.
(@@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { (@@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!({$($map)*})] $($rest)* @@array [$($elems,)* $crate::graphql::input_value!({$($map)*})] $($rest)*
) )
}; };
// Next element is `true`, `false` or enum ident followed by comma. // Next element is `true`, `false` or enum ident followed by comma.
(@@array [$($elems:expr,)*] $ident:ident, $($rest:tt)*) => { (@@array [$($elems:expr,)*] $ident:ident, $($rest:tt)*) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!($ident),] $($rest)* @@array [$($elems,)* $crate::graphql::input_value!($ident),] $($rest)*
) )
}; };
// Next element is `true`, `false` or enum ident without trailing comma. // Next element is `true`, `false` or enum ident without trailing comma.
(@@array [$($elems:expr,)*] $last:ident ) => { (@@array [$($elems:expr,)*] $last:ident ) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!($last)] @@array [$($elems,)* $crate::graphql::input_value!($last)]
) )
}; };
// Next element is an expression followed by comma. // Next element is an expression followed by comma.
(@@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { (@@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!($next),] $($rest)* @@array [$($elems,)* $crate::graphql::input_value!($next),] $($rest)*
) )
}; };
// Last element is an expression with no trailing comma. // Last element is an expression with no trailing comma.
(@@array [$($elems:expr,)*] $last:expr) => { (@@array [$($elems:expr,)*] $last:expr) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@array [$($elems,)* $crate::graphql_input_value!($last)] @@array [$($elems,)* $crate::graphql::input_value!($last)]
) )
}; };
// Comma after the most recent element. // Comma after the most recent element.
(@@array [$($elems:expr),*] , $($rest:tt)*) => { (@@array [$($elems:expr),*] , $($rest:tt)*) => {
$crate::graphql_input_value!(@@array [$($elems,)*] $($rest)*) $crate::graphql::input_value!(@@array [$($elems,)*] $($rest)*)
}; };
// Unexpected token after most recent element. // Unexpected token after most recent element.
(@@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { (@@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => {
$crate::graphql_input_value!(@unexpected $unexpected) $crate::graphql::input_value!(@unexpected $unexpected)
}; };
//////////// ////////////
@ -192,12 +189,12 @@ macro_rules! graphql_input_value {
$crate::Spanning::unlocated(($($key)+).into()), $crate::Spanning::unlocated(($($key)+).into()),
$crate::Spanning::unlocated($value), $crate::Spanning::unlocated($value),
)); ));
$crate::graphql_input_value!(@@object $object () ($($rest)*) ($($rest)*)); $crate::graphql::input_value!(@@object $object () ($($rest)*) ($($rest)*));
}; };
// Current entry followed by unexpected token. // Current entry followed by unexpected token.
(@@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { (@@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
$crate::graphql_input_value!(@unexpected $unexpected); $crate::graphql::input_value!(@unexpected $unexpected);
}; };
// Insert the last entry without trailing comma. // Insert the last entry without trailing comma.
@ -210,114 +207,114 @@ macro_rules! graphql_input_value {
// Next value is `null`. // Next value is `null`.
(@@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!(null)) $($rest)* ($crate::graphql::input_value!(null)) $($rest)*
); );
}; };
// Next value is `None`. // Next value is `None`.
(@@object $object:ident ($($key:tt)+) (: None $($rest:tt)*) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: None $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!(None)) $($rest)* ($crate::graphql::input_value!(None)) $($rest)*
); );
}; };
// Next value is a variable. // Next value is a variable.
(@@object $object:ident ($($key:tt)+) (: @$var:ident $($rest:tt)*) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: @$var:ident $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!(@$var)) $($rest)* ($crate::graphql::input_value!(@$var)) $($rest)*
); );
}; };
// Next value is an array. // Next value is an array.
(@@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!([$($array)*])) $($rest)* ($crate::graphql::input_value!([$($array)*])) $($rest)*
); );
}; };
// Next value is a map. // Next value is a map.
(@@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!({$($map)*})) $($rest)* ($crate::graphql::input_value!({$($map)*})) $($rest)*
); );
}; };
// Next value is `true`, `false` or enum ident followed by comma. // Next value is `true`, `false` or enum ident followed by comma.
(@@object $object:ident ($($key:tt)+) (: $ident:ident , $($rest:tt)*) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: $ident:ident , $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!($ident)) , $($rest)* ($crate::graphql::input_value!($ident)) , $($rest)*
); );
}; };
// Next value is `true`, `false` or enum ident without trailing comma. // Next value is `true`, `false` or enum ident without trailing comma.
(@@object $object:ident ($($key:tt)+) (: $last:ident ) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: $last:ident ) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!($last)) ($crate::graphql::input_value!($last))
); );
}; };
// Next value is an expression followed by comma. // Next value is an expression followed by comma.
(@@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!($value)) , $($rest)* ($crate::graphql::input_value!($value)) , $($rest)*
); );
}; };
// Last value is an expression with no trailing comma. // Last value is an expression with no trailing comma.
(@@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
[$($key)+] [$($key)+]
($crate::graphql_input_value!($value)) ($crate::graphql::input_value!($value))
); );
}; };
// Missing value for last entry. Trigger a reasonable error message. // Missing value for last entry. Trigger a reasonable error message.
(@@object $object:ident ($($key:tt)+) (:) $copy:tt) => { (@@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
// "unexpected end of macro invocation" // "unexpected end of macro invocation"
$crate::graphql_input_value!(); $crate::graphql::input_value!();
}; };
// Missing colon and value for last entry. Trigger a reasonable error // Missing colon and value for last entry. Trigger a reasonable error
// message. // message.
(@@object $object:ident ($($key:tt)+) () $copy:tt) => { (@@object $object:ident ($($key:tt)+) () $copy:tt) => {
// "unexpected end of macro invocation" // "unexpected end of macro invocation"
$crate::graphql_input_value!(); $crate::graphql::input_value!();
}; };
// Misplaced colon. Trigger a reasonable error message. // Misplaced colon. Trigger a reasonable error message.
(@@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { (@@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
// Takes no arguments so "no rules expected the token `:`". // Takes no arguments so "no rules expected the token `:`".
$crate::graphql_input_value!(@unexpected $colon); $crate::graphql::input_value!(@unexpected $colon);
}; };
// Found a comma inside a key. Trigger a reasonable error message. // Found a comma inside a key. Trigger a reasonable error message.
(@@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { (@@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
// Takes no arguments so "no rules expected the token `,`". // Takes no arguments so "no rules expected the token `,`".
$crate::graphql_input_value!(@unexpected $comma); $crate::graphql::input_value!(@unexpected $comma);
}; };
// Key is fully parenthesized. This avoids `clippy::double_parens` false // Key is fully parenthesized. This avoids `clippy::double_parens` false
// positives because the parenthesization may be necessary here. // positives because the parenthesization may be necessary here.
(@@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { (@@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
($key) ($key)
(: $($rest)*) (: $($rest)*) (: $($rest)*) (: $($rest)*)
@ -326,12 +323,12 @@ macro_rules! graphql_input_value {
// Refuse to absorb colon token into key expression. // Refuse to absorb colon token into key expression.
(@@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => { (@@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
$crate::graphql_input_value!(@@unexpected $($unexpected)+); $crate::graphql::input_value!(@@unexpected $($unexpected)+);
}; };
// Munch a token into the current key. // Munch a token into the current key.
(@@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { (@@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!( $crate::graphql::input_value!(
@@object $object @@object $object
($($key)* $tt) ($($key)* $tt)
($($rest)*) ($($rest)*) ($($rest)*) ($($rest)*)
@ -349,109 +346,107 @@ macro_rules! graphql_input_value {
////////////// //////////////
([ $($arr:tt)* ]$(,)?) => { ([ $($arr:tt)* ]$(,)?) => {
$crate::graphql_input_value!(@@array [] $($arr)*) $crate::graphql::input_value!(@@array [] $($arr)*)
}; };
({}$(,)?) => { ({}$(,)?) => {
$crate::InputValue::parsed_object(vec![]) $crate::graphql::InputValue::parsed_object(vec![])
}; };
({ $($map:tt)+ }$(,)?) => { ({ $($map:tt)+ }$(,)?) => {
$crate::InputValue::parsed_object({ $crate::graphql::InputValue::parsed_object({
let mut object = vec![]; let mut object = vec![];
$crate::graphql_input_value!(@@object object () ($($map)*) ($($map)*)); $crate::graphql::input_value!(@@object object () ($($map)*) ($($map)*));
object object
}) })
}; };
(null$(,)?) => ($crate::InputValue::null()); (null$(,)?) => ($crate::graphql::InputValue::null());
(None$(,)?) => ($crate::InputValue::null()); (None$(,)?) => ($crate::graphql::InputValue::null());
(true$(,)?) => ($crate::InputValue::from(true)); (true$(,)?) => ($crate::graphql::InputValue::from(true));
(false$(,)?) => ($crate::InputValue::from(false)); (false$(,)?) => ($crate::graphql::InputValue::from(false));
(@$var:ident$(,)?) => ($crate::InputValue::variable(stringify!($var))); (@$var:ident$(,)?) => ($crate::graphql::InputValue::variable(stringify!($var)));
($enum:ident$(,)?) => ($crate::InputValue::enum_value(stringify!($enum))); ($enum:ident$(,)?) => ($crate::graphql::InputValue::enum_value(stringify!($enum)));
(($e:expr)$(,)?) => ($crate::InputValue::from($e)); (($e:expr)$(,)?) => ($crate::graphql::InputValue::from($e));
($e:expr$(,)?) => ($crate::InputValue::from($e)); ($e:expr$(,)?) => ($crate::graphql::InputValue::from($e));
} }
#[doc(inline)]
pub(super) use input_value;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use indexmap::{indexmap, IndexMap}; use indexmap::{indexmap, IndexMap};
type V = crate::InputValue; use crate::graphql;
use super::input_value;
type V = graphql::InputValue;
#[test] #[test]
fn null() { fn null() {
assert_eq!(graphql_input_value!(null), V::Null); assert_eq!(input_value!(null), V::Null);
} }
#[test] #[test]
fn scalar() { fn scalar() {
let val = 42; let val = 42;
assert_eq!(graphql_input_value!(1), V::scalar(1)); assert_eq!(input_value!(1), V::scalar(1));
assert_eq!(graphql_input_value!("val"), V::scalar("val")); assert_eq!(input_value!("val"), V::scalar("val"));
assert_eq!(graphql_input_value!(1.34), V::scalar(1.34)); assert_eq!(input_value!(1.34), V::scalar(1.34));
assert_eq!(graphql_input_value!(false), V::scalar(false)); assert_eq!(input_value!(false), V::scalar(false));
assert_eq!(graphql_input_value!(1 + 2), V::scalar(3)); assert_eq!(input_value!(1 + 2), V::scalar(3));
assert_eq!(graphql_input_value!((val)), V::scalar(42)); assert_eq!(input_value!((val)), V::scalar(42));
} }
#[test] #[test]
fn r#enum() { fn r#enum() {
assert_eq!(graphql_input_value!(ENUM), V::enum_value("ENUM")); assert_eq!(input_value!(ENUM), V::enum_value("ENUM"));
assert_eq!(graphql_input_value!(lowercase), V::enum_value("lowercase")); assert_eq!(input_value!(lowercase), V::enum_value("lowercase"));
} }
#[test] #[test]
fn variable() { fn variable() {
assert_eq!(graphql_input_value!(@var), V::variable("var")); assert_eq!(input_value!(@var), V::variable("var"));
assert_eq!(graphql_input_value!(@array), V::variable("array")); assert_eq!(input_value!(@array), V::variable("array"));
assert_eq!(graphql_input_value!(@object), V::variable("object")); assert_eq!(input_value!(@object), V::variable("object"));
} }
#[test] #[test]
fn list() { fn list() {
let val = 42; let val = 42;
assert_eq!(graphql_input_value!([]), V::list(vec![])); assert_eq!(input_value!([]), V::list(vec![]));
assert_eq!(graphql_input_value!([null]), V::list(vec![V::Null])); assert_eq!(input_value!([null]), V::list(vec![V::Null]));
assert_eq!(graphql_input_value!([1]), V::list(vec![V::scalar(1)])); assert_eq!(input_value!([1]), V::list(vec![V::scalar(1)]));
assert_eq!(graphql_input_value!([1 + 2]), V::list(vec![V::scalar(3)])); assert_eq!(input_value!([1 + 2]), V::list(vec![V::scalar(3)]));
assert_eq!(graphql_input_value!([(val)]), V::list(vec![V::scalar(42)])); assert_eq!(input_value!([(val)]), V::list(vec![V::scalar(42)]));
assert_eq!(input_value!([ENUM]), V::list(vec![V::enum_value("ENUM")]));
assert_eq!( assert_eq!(
graphql_input_value!([ENUM]), input_value!([lowercase]),
V::list(vec![V::enum_value("ENUM")]),
);
assert_eq!(
graphql_input_value!([lowercase]),
V::list(vec![V::enum_value("lowercase")]), V::list(vec![V::enum_value("lowercase")]),
); );
assert_eq!(input_value!([@var]), V::list(vec![V::variable("var")]),);
assert_eq!(input_value!([@array]), V::list(vec![V::variable("array")]));
assert_eq!( assert_eq!(
graphql_input_value!([@var]), input_value!([@object]),
V::list(vec![V::variable("var")]),
);
assert_eq!(
graphql_input_value!([@array]),
V::list(vec![V::variable("array")]),
);
assert_eq!(
graphql_input_value!([@object]),
V::list(vec![V::variable("object")]), V::list(vec![V::variable("object")]),
); );
assert_eq!( assert_eq!(
graphql_input_value!([1, [2], 3]), input_value!([1, [2], 3]),
V::list(vec![ V::list(vec![
V::scalar(1), V::scalar(1),
V::list(vec![V::scalar(2)]), V::list(vec![V::scalar(2)]),
@ -459,7 +454,7 @@ mod tests {
]), ]),
); );
assert_eq!( assert_eq!(
graphql_input_value!([1, [2 + 3], 3]), input_value!([1, [2 + 3], 3]),
V::list(vec![ V::list(vec![
V::scalar(1), V::scalar(1),
V::list(vec![V::scalar(5)]), V::list(vec![V::scalar(5)]),
@ -467,7 +462,7 @@ mod tests {
]), ]),
); );
assert_eq!( assert_eq!(
graphql_input_value!([1, [ENUM], (val)]), input_value!([1, [ENUM], (val)]),
V::list(vec![ V::list(vec![
V::scalar(1), V::scalar(1),
V::list(vec![V::enum_value("ENUM")]), V::list(vec![V::enum_value("ENUM")]),
@ -475,7 +470,7 @@ mod tests {
]), ]),
); );
assert_eq!( assert_eq!(
graphql_input_value!([1 + 2, [(val)], @val]), input_value!([1 + 2, [(val)], @val]),
V::list(vec![ V::list(vec![
V::scalar(3), V::scalar(3),
V::list(vec![V::scalar(42)]), V::list(vec![V::scalar(42)]),
@ -483,7 +478,7 @@ mod tests {
]), ]),
); );
assert_eq!( assert_eq!(
graphql_input_value!([1, [@val], ENUM]), input_value!([1, [@val], ENUM]),
V::list(vec![ V::list(vec![
V::scalar(1), V::scalar(1),
V::list(vec![V::variable("val")]), V::list(vec![V::variable("val")]),
@ -495,68 +490,65 @@ mod tests {
#[test] #[test]
fn object() { fn object() {
let val = 42; let val = 42;
assert_eq!( assert_eq!(input_value!({}), V::object(IndexMap::<String, _>::new()));
graphql_input_value!({}),
V::object(IndexMap::<String, _>::new()),
);
assert_eq!( assert_eq!(
graphql_input_value!({ "key": null }), input_value!({ "key": null }),
V::object(indexmap! {"key" => V::Null}), V::object(indexmap! {"key" => V::Null}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({"key": 123}), input_value!({"key": 123}),
V::object(indexmap! {"key" => V::scalar(123)}), V::object(indexmap! {"key" => V::scalar(123)}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({"key": 1 + 2}), input_value!({"key": 1 + 2}),
V::object(indexmap! {"key" => V::scalar(3)}), V::object(indexmap! {"key" => V::scalar(3)}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({ "key": (val) }), input_value!({ "key": (val) }),
V::object(indexmap! {"key" => V::scalar(42)}), V::object(indexmap! {"key" => V::scalar(42)}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({"key": []}), input_value!({"key": []}),
V::object(indexmap! {"key" => V::list(vec![])}), V::object(indexmap! {"key" => V::list(vec![])}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({ "key": [null] }), input_value!({ "key": [null] }),
V::object(indexmap! {"key" => V::list(vec![V::Null])}), V::object(indexmap! {"key" => V::list(vec![V::Null])}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({"key": [1] }), input_value!({"key": [1] }),
V::object(indexmap! {"key" => V::list(vec![V::scalar(1)])}), V::object(indexmap! {"key" => V::list(vec![V::scalar(1)])}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({"key": [1 + 2] }), input_value!({"key": [1 + 2] }),
V::object(indexmap! {"key" => V::list(vec![V::scalar(3)])}), V::object(indexmap! {"key" => V::list(vec![V::scalar(3)])}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({ "key": [(val)] }), input_value!({ "key": [(val)] }),
V::object(indexmap! {"key" => V::list(vec![V::scalar(42)])}), V::object(indexmap! {"key" => V::list(vec![V::scalar(42)])}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({ "key": ENUM }), input_value!({ "key": ENUM }),
V::object(indexmap! {"key" => V::enum_value("ENUM")}), V::object(indexmap! {"key" => V::enum_value("ENUM")}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({ "key": lowercase }), input_value!({ "key": lowercase }),
V::object(indexmap! {"key" => V::enum_value("lowercase")}), V::object(indexmap! {"key" => V::enum_value("lowercase")}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({"key": @val}), input_value!({"key": @val}),
V::object(indexmap! {"key" => V::variable("val")}), V::object(indexmap! {"key" => V::variable("val")}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({"key": @array }), input_value!({"key": @array }),
V::object(indexmap! {"key" => V::variable("array")}), V::object(indexmap! {"key" => V::variable("array")}),
); );
assert_eq!( assert_eq!(
graphql_input_value!({ input_value!({
"inner": { "inner": {
"key1": (val), "key1": (val),
"key2": "val", "key2": "val",
@ -606,8 +598,8 @@ mod tests {
fn option() { fn option() {
let val = Some(42); let val = Some(42);
assert_eq!(graphql_input_value!(None), V::Null); assert_eq!(input_value!(None), V::Null);
assert_eq!(graphql_input_value!(Some(42)), V::scalar(42)); assert_eq!(input_value!(Some(42)), V::scalar(42));
assert_eq!(graphql_input_value!((val)), V::scalar(42)); assert_eq!(input_value!((val)), V::scalar(42));
} }
} }

View file

@ -6,9 +6,11 @@ pub mod helper;
#[macro_use] #[macro_use]
pub mod reflect; pub mod reflect;
#[macro_use] mod input_value;
mod graphql_input_value;
#[macro_use] #[macro_use]
mod graphql_value; mod graphql_value;
#[macro_use] #[macro_use]
mod graphql_vars; mod graphql_vars;
#[doc(inline)]
pub use self::input_value::input_value;