#[macro_export]
macro_rules! graphql_vars {
(@object $object:ident () () ()) => {};
(@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
let _ = $object.insert(($($key)+).into(), $value);
$crate::graphql_vars! {@object $object () ($($rest)*) ($($rest)*)};
};
(@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
$crate::graphql_vars! {@unexpected $unexpected};
};
(@object $object:ident [$($key:tt)+] ($value:expr)) => {
let _ = $object.insert(($($key)+).into(), $value);
};
(@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!(null)) $($rest)*
};
};
(@object $object:ident ($($key:tt)+) (: None $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!(None)) $($rest)*
};
};
(@object $object:ident ($($key:tt)+) (: @$var:ident $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!(@$var)) $($rest)*
};
};
(@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!([$($array)*])) $($rest)*
};
};
(@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!({$($map)*})) $($rest)*
};
};
(@object $object:ident ($($key:tt)+) (: $ident:ident , $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!($ident)) , $($rest)*
};
};
(@object $object:ident ($($key:tt)+) (: $last:ident ) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!($last))
};
};
(@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!($value)) , $($rest)*
};
};
(@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
$crate::graphql_vars! {
@object $object
[$($key)+]
($crate::graphql_input_value!($value))
};
};
(@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
$crate::graphql_vars! {};
};
(@object $object:ident ($($key:tt)+) () $copy:tt) => {
$crate::graphql_vars! {};
};
(@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
$crate::graphql_vars! {@unexpected $colon};
};
(@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
$crate::graphql_vars! {@unexpected $comma};
};
(@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object ($key) (: $($rest)*) (: $($rest)*)
};
};
(@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
$crate::graphql_vars! {@unexpected $($unexpected)+};
};
(@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
$crate::graphql_vars! {
@object $object
($($key)* $tt)
($($rest)*) ($($rest)*)
};
};
(@unexpected) => {};
() => {{ $crate::Variables::<_>::new() }};
( $($map:tt)+ ) => {{
let mut object = $crate::Variables::<_>::new();
$crate::graphql_vars! {@object object () ($($map)*) ($($map)*)};
object
}};
}
#[cfg(test)]
mod tests {
use indexmap::{IndexMap, indexmap};
type V = crate::Variables;
type IV = crate::InputValue;
#[test]
fn empty() {
assert_eq!(graphql_vars! {}, V::new());
}
#[test]
fn scalar() {
let val = 42;
assert_eq!(
graphql_vars! {"key": 123},
vec![("key".into(), IV::scalar(123))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": "val"},
vec![("key".into(), IV::scalar("val"))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": 1.23},
vec![("key".into(), IV::scalar(1.23))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": 1 + 2},
vec![("key".into(), IV::scalar(3))].into_iter().collect(),
);
assert_eq!(
graphql_vars! {"key": false},
vec![("key".into(), IV::scalar(false))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": (val)},
vec![("key".into(), IV::scalar(42))]
.into_iter()
.collect::<V>(),
);
}
#[test]
fn r#enum() {
assert_eq!(
graphql_vars! {"key": ENUM},
vec![("key".into(), IV::enum_value("ENUM"))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": lowercase},
vec![("key".into(), IV::enum_value("lowercase"))]
.into_iter()
.collect::<V>(),
);
}
#[test]
fn variable() {
assert_eq!(
graphql_vars! {"key": @var},
vec![("key".into(), IV::variable("var"))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": @array},
vec![("key".into(), IV::variable("array"))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": @object},
vec![("key".into(), IV::variable("object"))]
.into_iter()
.collect::<V>(),
);
}
#[test]
fn list() {
let val = 42;
assert_eq!(
graphql_vars! {"key": []},
vec![("key".into(), IV::list(vec![]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [null]},
vec![("key".into(), IV::list(vec![IV::Null]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [1]},
vec![("key".into(), IV::list(vec![IV::scalar(1)]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [1 + 2]},
vec![("key".into(), IV::list(vec![IV::scalar(3)]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [(val)]},
vec![("key".into(), IV::list(vec![IV::scalar(42)]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [ENUM]},
vec![("key".into(), IV::list(vec![IV::enum_value("ENUM")]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [lowercase]},
vec![("key".into(), IV::list(vec![IV::enum_value("lowercase")]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [@var]},
vec![("key".into(), IV::list(vec![IV::variable("var")]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [@array]},
vec![("key".into(), IV::list(vec![IV::variable("array")]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [@object]},
vec![("key".into(), IV::list(vec![IV::variable("object")]))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [1, [2], 3]},
vec![(
"key".into(),
IV::list(vec![
IV::scalar(1),
IV::list(vec![IV::scalar(2)]),
IV::scalar(3),
]),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [1, [2 + 3], 3]},
vec![(
"key".into(),
IV::list(vec![
IV::scalar(1),
IV::list(vec![IV::scalar(5)]),
IV::scalar(3),
]),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [1, [ENUM], (val)]},
vec![(
"key".into(),
IV::list(vec![
IV::scalar(1),
IV::list(vec![IV::enum_value("ENUM")]),
IV::scalar(42),
]),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [1 + 2, [(val)], @val]},
vec![(
"key".into(),
IV::list(vec![
IV::scalar(3),
IV::list(vec![IV::scalar(42)]),
IV::variable("val"),
]),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": [1, [@val], ENUM]},
vec![(
"key".into(),
IV::list(vec![
IV::scalar(1),
IV::list(vec![IV::variable("val")]),
IV::enum_value("ENUM"),
]),
)]
.into_iter()
.collect::<V>(),
);
}
#[test]
fn object() {
let val = 42;
assert_eq!(
graphql_vars! {"key": {}},
vec![("key".into(), IV::object(IndexMap::<String, _>::new()))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": null}},
vec![("key".into(), IV::object(indexmap! {"key" => IV::Null}))]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": 123}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::scalar(123)}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": 1 + 2}},
vec![("key".into(), IV::object(indexmap! {"key" => IV::scalar(3)}),)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": (val)}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::scalar(42)}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": []}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::list(vec![])}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": [null]}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::list(vec![IV::Null])}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": [1]}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::list(vec![IV::scalar(1)])}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": [1 + 2]}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::list(vec![IV::scalar(3)])}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": [(val)]}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::list(vec![IV::scalar(42)])}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": ENUM}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::enum_value("ENUM")}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": lowercase}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::enum_value("lowercase")}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": @val}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::variable("val")}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {"key": {"key": @array}},
vec![(
"key".into(),
IV::object(indexmap! {"key" => IV::variable("array")}),
)]
.into_iter()
.collect::<V>(),
);
assert_eq!(
graphql_vars! {
"inner": {
"key1": (val),
"key2": "val",
"key3": [{
"inner": 42,
}, {
"inner": ENUM,
"even-more": {
"var": @var,
},
}],
"key4": [1, ["val", 1 + 3], null, @array],
},
"more": @var,
},
vec![
(
"inner".into(),
IV::object(indexmap! {
"key1" => IV::scalar(42),
"key2" => IV::scalar("val"),
"key3" => IV::list(vec![
IV::object(indexmap! {
"inner" => IV::scalar(42),
}),
IV::object(indexmap! {
"inner" => IV::enum_value("ENUM"),
"even-more" => IV::object(indexmap! {
"var" => IV::variable("var"),
}),
}),
]),
"key4" => IV::list(vec![
IV::scalar(1),
IV::list(vec![
IV::scalar("val"),
IV::scalar(4),
]),
IV::Null,
IV::variable("array"),
]),
}),
),
("more".into(), IV::variable("var")),
]
.into_iter()
.collect::<V>(),
);
}
}