#[macro_export]
#[doc(hidden)]
macro_rules! impl_selectable_expression {
($struct_name:ident) => {
impl_selectable_expression!(ty_params = (), struct_ty = $struct_name,);
};
($struct_name:ident<$($ty_params:ident),+>) => {
impl_selectable_expression!(
ty_params = ($($ty_params),+),
struct_ty = $struct_name<$($ty_params),+>,
);
};
(ty_params = ($($ty_params:ident),*), struct_ty = $struct_ty:ty,) => {
impl<$($ty_params,)* QS> $crate::expression::SelectableExpression<QS>
for $struct_ty where
$struct_ty: $crate::expression::AppearsOnTable<QS>,
$($ty_params: $crate::expression::SelectableExpression<QS>,)*
{
}
impl<$($ty_params,)* QS> $crate::expression::AppearsOnTable<QS>
for $struct_ty where
$struct_ty: $crate::expression::Expression,
$($ty_params: $crate::expression::AppearsOnTable<QS>,)*
{
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __diesel_parse_type_args {
(
data = $data:tt,
callback = $callback:ident,
tokens = $tokens:tt,
) => {
__diesel_parse_type_args! {
data = $data,
callback = $callback,
args = (),
bounds = (),
tokens = $tokens,
}
};
(
data = $data:tt,
callback = $callback:ident,
args = ($($args:tt)*),
bounds = ($($bounds:tt)*),
tokens = ($next_arg:ident : $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
brackets = (),
data = $data,
callback = $callback,
args = ($($args)* $next_arg,),
bounds = ($($bounds)* $next_arg:),
tokens = ($($tokens)*),
}
};
(
data = $data:tt,
callback = $callback:ident,
args = ($($args:tt)*),
bounds = ($($bounds:tt)*),
tokens = ($next_arg:ident $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
data = $data,
callback = $callback,
args = ($($args)* $next_arg,),
bounds = ($($bounds)* $next_arg,),
tokens = ($($tokens)*),
}
};
(
brackets = (),
data = $data:tt,
callback = $callback:ident,
args = $args:tt,
bounds = ($($bounds:tt)*),
tokens = (> $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
data = $data,
callback = $callback,
args = $args,
bounds = ($($bounds)*,),
tokens = (> $($tokens)*),
}
};
(
brackets = (),
data = $data:tt,
callback = $callback:ident,
args = $args:tt,
bounds = ($($bounds:tt)*),
tokens = (, $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
data = $data,
callback = $callback,
args = $args,
bounds = ($($bounds)* ,),
tokens = ($($tokens)*),
}
};
(
brackets = ($($brackets:tt)*),
data = $data:tt,
callback = $callback:ident,
args = $args:tt,
bounds = ($($bounds:tt)*),
tokens = (< $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
brackets = (< $($brackets)*),
data = $data,
callback = $callback,
args = $args,
bounds = ($($bounds)* <),
tokens = ($($tokens)*),
}
};
(
brackets = (< $($brackets:tt)*),
data = $data:tt,
callback = $callback:ident,
args = $args:tt,
bounds = ($($bounds:tt)*),
tokens = (>> $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
brackets = ($($brackets)*),
data = $data,
callback = $callback,
args = $args,
bounds = ($($bounds)* >),
tokens = (> $($tokens)*),
}
};
(
brackets = (< $($brackets:tt)*),
data = $data:tt,
callback = $callback:ident,
args = $args:tt,
bounds = ($($bounds:tt)*),
tokens = (> $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
brackets = ($($brackets)*),
data = $data,
callback = $callback,
args = $args,
bounds = ($($bounds)* >),
tokens = ($($tokens)*),
}
};
(
brackets = $brackets:tt,
data = $data:tt,
callback = $callback:ident,
args = $args:tt,
bounds = ($($bounds:tt)*),
tokens = ($token:tt $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
brackets = $brackets,
data = $data,
callback = $callback,
args = $args,
bounds = ($($bounds)* $token),
tokens = ($($tokens)*),
}
};
(
data = $data:tt,
callback = $callback:ident,
args = $args:tt,
bounds = $bounds:tt,
tokens = (, $($tokens:tt)*),
) => {
__diesel_parse_type_args! {
data = $data,
callback = $callback,
args = $args,
bounds = $bounds,
tokens = ($($tokens)*),
}
};
(
data = $data:tt,
callback = $callback:ident,
args = $args:tt,
bounds = $bounds:tt,
tokens = (> $($tokens:tt)*),
) => {
$callback! {
data = $data,
type_args = $args,
type_args_with_bounds = $bounds,
unparsed_tokens = ($($tokens)*),
}
};
}
#[test]
fn parse_type_args_empty() {
let expected = stringify!(
data = (),
type_args = (),
type_args_with_bounds = (),
unparsed_tokens = (),
);
let actual = __diesel_parse_type_args! {
data = (),
callback = stringify,
tokens = (>),
};
assert_eq!(expected, actual);
}
#[test]
fn parse_type_args_simple() {
let expected = stringify!(
data = (foo),
type_args = (T,),
type_args_with_bounds = (T,),
unparsed_tokens = (),
);
let actual = __diesel_parse_type_args! {
data = (foo),
callback = stringify,
tokens = (T>),
};
assert_eq!(expected, actual);
let actual = __diesel_parse_type_args! {
data = (foo),
callback = stringify,
tokens = (T,>),
};
assert_eq!(expected, actual);
}
#[test]
fn parse_type_args_multiple() {
let expected = stringify!(
data = (foo),
type_args = (T, U,),
type_args_with_bounds = (T, U,),
unparsed_tokens = (),
);
let actual = __diesel_parse_type_args! {
data = (foo),
callback = stringify,
tokens = (T,U>),
};
assert_eq!(expected, actual);
let actual = __diesel_parse_type_args! {
data = (foo),
callback = stringify,
tokens = (T,U,>),
};
assert_eq!(expected, actual);
}
#[test]
fn parse_type_args_with_bounds() {
let expected = stringify!(
data = (foo),
type_args = (T, U,),
type_args_with_bounds = (T: Foo + Bar, U: Baz,),
unparsed_tokens = (),
);
let actual = __diesel_parse_type_args! {
data = (foo),
callback = stringify,
tokens = (T: Foo + Bar, U: Baz>),
};
assert_eq!(expected, actual);
let actual = __diesel_parse_type_args! {
data = (foo),
callback = stringify,
tokens = (T: Foo + Bar, U: Baz,>),
};
assert_eq!(expected, actual);
}
#[test]
fn parse_type_args_with_bounds_containing_braces_and_commas() {
let expected = stringify!(
data = (foo),
type_args = (T,U,),
type_args_with_bounds = (T: Foo<X> + Bar<U, V>,U: Baz<Vec<i32>, String>,),
unparsed_tokens = (),
);
let actual = __diesel_parse_type_args! {
data = (foo),
callback = stringify,
tokens = (T: Foo<X> + Bar<U, V>,U: Baz<Vec<i32>, String>>),
};
assert_eq!(expected, actual);
let actual = __diesel_parse_type_args! {
data = (foo),
callback = stringify,
tokens = (T: Foo<X> + Bar<U, V>,U: Baz<Vec<i32>, String>,>),
};
assert_eq!(expected, actual);
}
#[test]
fn parse_type_args_with_trailer() {
let expected = stringify!(
data = (
meta = (#[aggregate]),
fn_name = max,
),
type_args = (ST,),
type_args_with_bounds = (ST: SqlOrd + IntoNullable,),
unparsed_tokens = ((expr: ST) -> ST::Nullable),
);
let actual = __diesel_parse_type_args! {
data = (
meta = (#[aggregate]),
fn_name = max,
),
callback = stringify,
tokens = (ST: SqlOrd + IntoNullable>(expr: ST) -> ST::Nullable),
};
assert_eq!(expected, actual);
}
#[test]
fn parse_type_args_with_existentials_and_lifetimes() {
let expected = stringify! (
data = (),
type_args = (ST,U,),
type_args_with_bounds = (ST: for<'a> Foo<'a, U> + 'static, U,),
unparsed_tokens = (),
);
let actual = __diesel_parse_type_args! {
data = (),
callback = stringify,
tokens = (ST: for<'a> Foo<'a, U> + 'static, U>),
};
assert_eq!(expected, actual);
}