#[macro_export]
macro_rules! graphql_value {
(@array [$($elems:expr,)*]) => {
$crate::Value::list(vec![
$( $elems, )*
])
};
(@array [$($elems:expr),*]) => {
$crate::Value::list(vec![
$( $crate::graphql_value!($elems), )*
])
};
(@array [$($elems:expr,)*] null $($rest:tt)*) => {
$crate::graphql_value!(
@array [$($elems,)* $crate::graphql_value!(null)] $($rest)*
)
};
(@array [$($elems:expr,)*] None $($rest:tt)*) => {
$crate::graphql_value!(
@array [$($elems,)* $crate::graphql_value!(None)] $($rest)*
)
};
(@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => {
$crate::graphql_value!(
@array [$($elems,)* $crate::graphql_value!([$($array)*])] $($rest)*
)
};
(@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => {
$crate::graphql_value!(
@array [$($elems,)* $crate::graphql_value!({$($map)*})] $($rest)*
)
};
(@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => {
$crate::graphql_value!(
@array [$($elems,)* $crate::graphql_value!($next),] $($rest)*
)
};
(@array [$($elems:expr,)*] $last:expr) => {
$crate::graphql_value!(
@array [$($elems,)* $crate::graphql_value!($last)]
)
};
(@array [$($elems:expr),*] , $($rest:tt)*) => {
$crate::graphql_value!(@array [$($elems,)*] $($rest)*)
};
(@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => {
$crate::graphql_value!(@unexpected $unexpected)
};
(@object $object:ident () () ()) => {};
(@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
let _ = $object.add_field(($($key)+), $value);
$crate::graphql_value!(@object $object () ($($rest)*) ($($rest)*));
};
(@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
$crate::graphql_value!(@unexpected $unexpected);
};
(@object $object:ident [$($key:tt)+] ($value:expr)) => {
let _ = $object.add_field(($($key)+), $value);
};
(@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
$crate::graphql_value!(
@object $object
[$($key)+]
($crate::graphql_value!(null)) $($rest)*
);
};
(@object $object:ident ($($key:tt)+) (: None $($rest:tt)*) $copy:tt) => {
$crate::graphql_value!(
@object $object
[$($key)+]
($crate::graphql_value!(None)) $($rest)*
);
};
(@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
$crate::graphql_value!(
@object $object
[$($key)+]
($crate::graphql_value!([$($array)*])) $($rest)*
);
};
(@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
$crate::graphql_value!(
@object $object
[$($key)+]
($crate::graphql_value!({$($map)*})) $($rest)*
);
};
(@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
$crate::graphql_value!(
@object $object
[$($key)+]
($crate::graphql_value!($value)) , $($rest)*
);
};
(@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
$crate::graphql_value!(
@object $object
[$($key)+]
($crate::graphql_value!($value))
);
};
(@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
$crate::graphql_value!();
};
(@object $object:ident ($($key:tt)+) () $copy:tt) => {
$crate::graphql_value!();
};
(@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
$crate::graphql_value!(@unexpected $colon);
};
(@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
$crate::graphql_value!(@unexpected $comma);
};
(@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
$crate::graphql_value!(@object $object ($key) (: $($rest)*) (: $($rest)*));
};
(@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
$crate::graphql_value!(@unexpected $($unexpected)+);
};
(@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
$crate::graphql_value!(
@object $object
($($key)* $tt)
($($rest)*) ($($rest)*)
);
};
(@unexpected) => {};
([ $($arr:tt)* ]$(,)?) => {
$crate::graphql_value!(@array [] $($arr)*)
};
({}$(,)?) => {
$crate::Value::object($crate::Object::with_capacity(0))
};
({ $($map:tt)+ }$(,)?) => {
$crate::Value::object({
let mut object = $crate::Object::with_capacity(0);
$crate::graphql_value!(@object object () ($($map)*) ($($map)*));
object
})
};
(null$(,)?) => ($crate::Value::null());
(None$(,)?) => ($crate::Value::null());
($e:expr$(,)?) => ($crate::Value::from($e));
}
#[cfg(test)]
mod tests {
type V = crate::Value;
#[test]
fn null() {
assert_eq!(graphql_value!(null), V::Null);
}
#[test]
fn scalar() {
let val = 42;
assert_eq!(graphql_value!(1), V::scalar(1));
assert_eq!(graphql_value!("val"), V::scalar("val"));
assert_eq!(graphql_value!(1.34), V::scalar(1.34));
assert_eq!(graphql_value!(false), V::scalar(false));
assert_eq!(graphql_value!(1 + 2), V::scalar(3));
assert_eq!(graphql_value!(val), V::scalar(42));
}
#[test]
fn list() {
let val = 42;
assert_eq!(graphql_value!([]), V::list(vec![]));
assert_eq!(graphql_value!([null]), V::list(vec![V::Null]));
assert_eq!(graphql_value!([1]), V::list(vec![V::scalar(1)]));
assert_eq!(graphql_value!([1 + 2]), V::list(vec![V::scalar(3)]));
assert_eq!(graphql_value!([val]), V::list(vec![V::scalar(42)]));
assert_eq!(
graphql_value!([1, [2], 3]),
V::list(vec![
V::scalar(1),
V::list(vec![V::scalar(2)]),
V::scalar(3),
]),
);
assert_eq!(
graphql_value!(["string", [2 + 3], true]),
V::list(vec![
V::scalar("string"),
V::list(vec![V::scalar(5)]),
V::scalar(true),
]),
);
}
#[test]
fn object() {
let val = 42;
assert_eq!(
graphql_value!({}),
V::object(Vec::<(String, _)>::new().into_iter().collect()),
);
assert_eq!(
graphql_value!({ "key": null }),
V::object(vec![("key", V::Null)].into_iter().collect()),
);
assert_eq!(
graphql_value!({ "key": 123 }),
V::object(vec![("key", V::scalar(123))].into_iter().collect()),
);
assert_eq!(
graphql_value!({ "key": 1 + 2 }),
V::object(vec![("key", V::scalar(3))].into_iter().collect()),
);
assert_eq!(
graphql_value!({ "key": [] }),
V::object(vec![("key", V::list(vec![]))].into_iter().collect()),
);
assert_eq!(
graphql_value!({ "key": [null] }),
V::object(vec![("key", V::list(vec![V::Null]))].into_iter().collect()),
);
assert_eq!(
graphql_value!({ "key": [1] }),
V::object(
vec![("key", V::list(vec![V::scalar(1)]))]
.into_iter()
.collect(),
),
);
assert_eq!(
graphql_value!({ "key": [1 + 2] }),
V::object(
vec![("key", V::list(vec![V::scalar(3)]))]
.into_iter()
.collect(),
),
);
assert_eq!(
graphql_value!({ "key": [val] }),
V::object(
vec![("key", V::list(vec![V::scalar(42)]))]
.into_iter()
.collect(),
),
);
}
#[test]
fn option() {
let val = Some(42);
assert_eq!(graphql_value!(None), V::Null);
assert_eq!(graphql_value!(Some(42)), V::scalar(42));
assert_eq!(graphql_value!(val), V::scalar(42));
}
}