#[macro_export]
macro_rules! graphql_input_value {
(@@array [$($elems:expr,)*]) => {
$crate::InputValue::list(vec![
$( $elems, )*
])
};
(@@array [$($elems:expr),*]) => {
$crate::InputValue::list(vec![
$( $elems, )*
])
};
(@@array [$($elems:expr,)*] null $($rest:tt)*) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!(null)] $($rest)*
)
};
(@@array [$($elems:expr,)*] None $($rest:tt)*) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!(None)] $($rest)*
)
};
(@@array [$($elems:expr,)*] @$var:ident $($rest:tt)*) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!(@$var)] $($rest)*
)
};
(@@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!([$($array)*])] $($rest)*
)
};
(@@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!({$($map)*})] $($rest)*
)
};
(@@array [$($elems:expr,)*] $ident:ident, $($rest:tt)*) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!($ident),] $($rest)*
)
};
(@@array [$($elems:expr,)*] $last:ident ) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!($last)]
)
};
(@@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!($next),] $($rest)*
)
};
(@@array [$($elems:expr,)*] $last:expr) => {
$crate::graphql_input_value!(
@@array [$($elems,)* $crate::graphql_input_value!($last)]
)
};
(@@array [$($elems:expr),*] , $($rest:tt)*) => {
$crate::graphql_input_value!(@@array [$($elems,)*] $($rest)*)
};
(@@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => {
$crate::graphql_input_value!(@unexpected $unexpected)
};
(@@object $object:ident () () ()) => {};
(@@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
$object.push((
$crate::Spanning::unlocated(($($key)+).into()),
$crate::Spanning::unlocated($value),
));
$crate::graphql_input_value!(@@object $object () ($($rest)*) ($($rest)*));
};
(@@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
$crate::graphql_input_value!(@unexpected $unexpected);
};
(@@object $object:ident [$($key:tt)+] ($value:expr)) => {
$object.push((
$crate::Spanning::unlocated(($($key)+).into()),
$crate::Spanning::unlocated($value),
));
};
(@@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!(null)) $($rest)*
);
};
(@@object $object:ident ($($key:tt)+) (: None $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!(None)) $($rest)*
);
};
(@@object $object:ident ($($key:tt)+) (: @$var:ident $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!(@$var)) $($rest)*
);
};
(@@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!([$($array)*])) $($rest)*
);
};
(@@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!({$($map)*})) $($rest)*
);
};
(@@object $object:ident ($($key:tt)+) (: $ident:ident , $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!($ident)) , $($rest)*
);
};
(@@object $object:ident ($($key:tt)+) (: $last:ident ) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!($last))
);
};
(@@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!($value)) , $($rest)*
);
};
(@@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
[$($key)+]
($crate::graphql_input_value!($value))
);
};
(@@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
$crate::graphql_input_value!();
};
(@@object $object:ident ($($key:tt)+) () $copy:tt) => {
$crate::graphql_input_value!();
};
(@@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
$crate::graphql_input_value!(@unexpected $colon);
};
(@@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
$crate::graphql_input_value!(@unexpected $comma);
};
(@@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
($key)
(: $($rest)*) (: $($rest)*)
);
};
(@@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
$crate::graphql_input_value!(@@unexpected $($unexpected)+);
};
(@@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
$crate::graphql_input_value!(
@@object $object
($($key)* $tt)
($($rest)*) ($($rest)*)
);
};
(@@unexpected) => {};
([ $($arr:tt)* ]$(,)?) => {
$crate::graphql_input_value!(@@array [] $($arr)*)
};
({}$(,)?) => {
$crate::InputValue::parsed_object(vec![])
};
({ $($map:tt)+ }$(,)?) => {
$crate::InputValue::parsed_object({
let mut object = vec![];
$crate::graphql_input_value!(@@object object () ($($map)*) ($($map)*));
object
})
};
(null$(,)?) => ($crate::InputValue::null());
(None$(,)?) => ($crate::InputValue::null());
(true$(,)?) => ($crate::IntoInputValue::into_input_value(true));
(false$(,)?) => ($crate::IntoInputValue::into_input_value(false));
(@$var:ident$(,)?) => ($crate::InputValue::variable(stringify!($var)));
($enum:ident$(,)?) => ($crate::InputValue::enum_value(stringify!($enum)));
(($e:expr)$(,)?) => ($crate::IntoInputValue::into_input_value($e));
($e:expr$(,)?) => ($crate::IntoInputValue::into_input_value($e));
}
#[cfg(test)]
mod tests {
use indexmap::{IndexMap, indexmap};
type V = crate::InputValue;
#[test]
fn null() {
assert_eq!(graphql_input_value!(null), V::Null);
}
#[test]
fn scalar() {
let val = 42;
assert_eq!(graphql_input_value!(1), V::scalar(1));
assert_eq!(graphql_input_value!("val"), V::scalar("val"));
assert_eq!(graphql_input_value!(1.34), V::scalar(1.34));
assert_eq!(graphql_input_value!(false), V::scalar(false));
assert_eq!(graphql_input_value!(1 + 2), V::scalar(3));
assert_eq!(graphql_input_value!((val)), V::scalar(42));
}
#[test]
fn r#enum() {
assert_eq!(graphql_input_value!(ENUM), V::enum_value("ENUM"));
assert_eq!(graphql_input_value!(lowercase), V::enum_value("lowercase"));
}
#[test]
fn variable() {
assert_eq!(graphql_input_value!(@var), V::variable("var"));
assert_eq!(graphql_input_value!(@array), V::variable("array"));
assert_eq!(graphql_input_value!(@object), V::variable("object"));
}
#[test]
fn list() {
let val = 42;
assert_eq!(graphql_input_value!([]), V::list(vec![]));
assert_eq!(graphql_input_value!([null]), V::list(vec![V::Null]));
assert_eq!(graphql_input_value!([1]), V::list(vec![V::scalar(1)]));
assert_eq!(graphql_input_value!([1 + 2]), V::list(vec![V::scalar(3)]));
assert_eq!(graphql_input_value!([(val)]), V::list(vec![V::scalar(42)]));
assert_eq!(
graphql_input_value!([ENUM]),
V::list(vec![V::enum_value("ENUM")]),
);
assert_eq!(
graphql_input_value!([lowercase]),
V::list(vec![V::enum_value("lowercase")]),
);
assert_eq!(
graphql_input_value!([@var]),
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")]),
);
assert_eq!(
graphql_input_value!([1, [2], 3]),
V::list(vec![
V::scalar(1),
V::list(vec![V::scalar(2)]),
V::scalar(3),
]),
);
assert_eq!(
graphql_input_value!([1, [2 + 3], 3]),
V::list(vec![
V::scalar(1),
V::list(vec![V::scalar(5)]),
V::scalar(3),
]),
);
assert_eq!(
graphql_input_value!([1, [ENUM], (val)]),
V::list(vec![
V::scalar(1),
V::list(vec![V::enum_value("ENUM")]),
V::scalar(42),
]),
);
assert_eq!(
graphql_input_value!([1 + 2, [(val)], @val]),
V::list(vec![
V::scalar(3),
V::list(vec![V::scalar(42)]),
V::variable("val"),
]),
);
assert_eq!(
graphql_input_value!([1, [@val], ENUM]),
V::list(vec![
V::scalar(1),
V::list(vec![V::variable("val")]),
V::enum_value("ENUM"),
]),
);
}
#[test]
fn object() {
let val = 42;
assert_eq!(
graphql_input_value!({}),
V::object(IndexMap::<String, _>::new()),
);
assert_eq!(
graphql_input_value!({ "key": null }),
V::object(indexmap! {"key" => V::Null}),
);
assert_eq!(
graphql_input_value!({"key": 123}),
V::object(indexmap! {"key" => V::scalar(123)}),
);
assert_eq!(
graphql_input_value!({"key": 1 + 2}),
V::object(indexmap! {"key" => V::scalar(3)}),
);
assert_eq!(
graphql_input_value!({ "key": (val) }),
V::object(indexmap! {"key" => V::scalar(42)}),
);
assert_eq!(
graphql_input_value!({"key": []}),
V::object(indexmap! {"key" => V::list(vec![])}),
);
assert_eq!(
graphql_input_value!({ "key": [null] }),
V::object(indexmap! {"key" => V::list(vec![V::Null])}),
);
assert_eq!(
graphql_input_value!({"key": [1] }),
V::object(indexmap! {"key" => V::list(vec![V::scalar(1)])}),
);
assert_eq!(
graphql_input_value!({"key": [1 + 2] }),
V::object(indexmap! {"key" => V::list(vec![V::scalar(3)])}),
);
assert_eq!(
graphql_input_value!({ "key": [(val)] }),
V::object(indexmap! {"key" => V::list(vec![V::scalar(42)])}),
);
assert_eq!(
graphql_input_value!({ "key": ENUM }),
V::object(indexmap! {"key" => V::enum_value("ENUM")}),
);
assert_eq!(
graphql_input_value!({ "key": lowercase }),
V::object(indexmap! {"key" => V::enum_value("lowercase")}),
);
assert_eq!(
graphql_input_value!({"key": @val}),
V::object(indexmap! {"key" => V::variable("val")}),
);
assert_eq!(
graphql_input_value!({"key": @array }),
V::object(indexmap! {"key" => V::variable("array")}),
);
assert_eq!(
graphql_input_value!({
"inner": {
"key1": (val),
"key2": "val",
"key3": [{
"inner": 42,
}, {
"inner": ENUM,
"even-more": {
"var": @var,
},
}],
"key4": [1, ["val", 1 + 3], null, @array],
},
"more": @var,
}),
V::object(indexmap! {
"inner" => V::object(indexmap! {
"key1" => V::scalar(42),
"key2" => V::scalar("val"),
"key3" => V::list(vec![
V::object(indexmap! {
"inner" => V::scalar(42),
}),
V::object(indexmap! {
"inner" => V::enum_value("ENUM"),
"even-more" => V::object(indexmap! {
"var" => V::variable("var"),
}),
}),
]),
"key4" => V::list(vec![
V::scalar(1),
V::list(vec![
V::scalar("val"),
V::scalar(4),
]),
V::Null,
V::variable("array"),
]),
}),
"more" => V::variable("var"),
}),
);
}
#[test]
fn option() {
let val = Some(42);
assert_eq!(graphql_input_value!(None), V::Null);
assert_eq!(graphql_input_value!(Some(42)), V::scalar(42));
assert_eq!(graphql_input_value!((val)), V::scalar(42));
}
}