#[macro_export]
macro_rules! Queryable {
(() $($body:tt)*) => {
Queryable! {
$($body)*
}
};
(
$(#[$ignore:meta])*
$(pub)* struct $($body:tt)*
) => {
Queryable! {
$($body)*
}
};
(
(
struct_name = $struct_name:ident,
$($headers:tt)*
),
fields = [$({
field_name: $field_name:ident,
column_name: $column_name:ident,
field_ty: $field_ty:ty,
field_kind: $field_kind:ident,
})+],
) => {
Queryable! {
$($headers)*
row_ty = ($($field_ty,)+),
row_pat = ($($field_name,)+),
build_expr = $struct_name { $($field_name: $field_name),+ },
}
};
(
$headers:tt,
fields = [$({
column_name: $column_name:ident,
field_ty: $field_ty:ty,
field_kind: $field_kind:ident,
})+],
) => {
Queryable! {
$headers,
fields = [$({
field_ty: $field_ty,
field_kind: $field_kind,
})+],
}
};
(
(
struct_name = $struct_name:ident,
$($headers:tt)*
),
fields = [$({
field_ty: $field_ty:ty,
field_kind: $field_kind:ident,
})+],
) => {
Queryable! {
$($headers)*
row_ty = ($($field_ty,)+),
row_pat = ($($field_kind,)+),
build_expr = $struct_name($($field_kind),+),
}
};
(
struct_ty = $struct_ty:ty,
generics = ($($generics:ident),*),
row_ty = $row_ty:ty,
row_pat = $row_pat:pat,
build_expr = $build_expr:expr,
) => {
impl<$($generics,)* __DB, __ST> $crate::Queryable<__ST, __DB> for $struct_ty where
__DB: $crate::backend::Backend + $crate::types::HasSqlType<__ST>,
$row_ty: $crate::types::FromSqlRow<__ST, __DB>,
{
type Row = $row_ty;
fn build(row: Self::Row) -> Self {
let $row_pat = row;
$build_expr
}
}
};
(
$struct_name:ident <$($generics:ident),*>
$body:tt $(;)*
) => {
__diesel_parse_struct_body! {
(
struct_name = $struct_name,
struct_ty = $struct_name<$($generics),*>,
generics = ($($generics),*),
),
callback = Queryable,
body = $body,
}
};
(
$struct_name:ident
$body:tt $(;)*
) => {
__diesel_parse_struct_body! {
(
struct_name = $struct_name,
struct_ty = $struct_name,
generics = (),
),
callback = Queryable,
body = $body,
}
};
}
#[cfg(test)]
mod tests {
use expression::dsl::sql;
use prelude::*;
use test_helpers::connection;
use types::Integer;
#[test]
fn named_struct_definition() {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct MyStruct {
foo: i32,
bar: i32,
}
Queryable! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct MyStruct {
foo: i32,
bar: i32,
}
}
let conn = connection();
let data = ::select(sql::<(Integer, Integer)>("1, 2")).get_result(&conn);
assert_eq!(Ok(MyStruct { foo: 1, bar: 2 }), data);
}
#[test]
fn tuple_struct() {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct MyStruct(i32, i32);
Queryable! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct MyStruct(#[column_name(foo)] i32, #[column_name(bar)] i32);
}
let conn = connection();
let data = ::select(sql::<(Integer, Integer)>("1, 2")).get_result(&conn);
assert_eq!(Ok(MyStruct(1, 2)), data);
}
#[test]
fn tuple_struct_without_column_name_annotations() {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct MyStruct(i32, i32);
Queryable! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct MyStruct(i32, i32);
}
let conn = connection();
let data = ::select(sql::<(Integer, Integer)>("1, 2")).get_result(&conn);
assert_eq!(Ok(MyStruct(1, 2)), data);
}
}