Move WithoutId to lib.rs

This commit is contained in:
dullbananas 2023-08-02 16:57:03 -07:00 committed by GitHub
parent c60611b5a8
commit 0c23e5213b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 68 deletions

View file

@ -29,9 +29,72 @@ extern crate macro_rules_attribute;
extern crate paste;
#[cfg(feature = "full")]
#[allow(unused_imports)]
#[macro_use]
mod without_id;
/// `macro_rules_attribute::derive(WithoutId!)` generates a variant of the struct with
/// `WithoutId` added to the name and no `id` field.
///
/// This is useful for making less redundant selections of multiple joined tables.
/// For example, selecting both `comment::post_id` and `post::id` is redundant if they
/// have the same value. In this case, the selection of `post::id` can be avoided by selecting
/// `PostWithoutId::as_select()` instead of `post::all_columns`.
///
/// This macro generates an `into_full` method, which converts to the sturct with `id`.
/// For example, `PostWithoutId` would have this:
///
/// `pub fn into_full(self, id: PostId) -> Post`
///
/// The `id` value can come from a column in another table, like `comment::post_id`.
///
/// The generated struct implements `Selectable` and `Queryable`.
macro_rules! WithoutId {
(
#[diesel(table_name = $table_name:ident)]
$(#[$_struct_meta:meta])*
$vis:vis struct $struct_name:ident {
$(#[$_id_meta:meta])*
$_id_vis:vis id: $id_type:ty,
$(
// TODO: more flexible and clean attribute matching
$(#[doc = $_doc1:tt])*
$(#[cfg($($cfgtt:tt)*)])*
$(#[cfg_attr($($cfgattrtt:tt)*)] $(#[doc = $_doc2:tt])*)*
$(#[serde($($serdett:tt)*)])*
$field_vis:vis $field_name:ident : $field_type:ty,
)*
}
) => {
::paste::paste! {
#[derive(::diesel::Queryable, ::diesel::Selectable)]
#[diesel(table_name = $table_name)]
$vis struct [<$struct_name WithoutId>] {
$(
$(#[cfg($($cfgtt)*)])*
$field_vis $field_name : $field_type,
)*
}
impl [<$struct_name WithoutId>] {
pub fn into_full(self, id: $id_type) -> $struct_name {
$struct_name {
id,
$($(#[cfg($($cfgtt)*)])* $field_name : self.$field_name,)*
}
}
}
}
};
// Keep on removing the first attribute until `diesel(table_name = ...)` becomes
// the first, which will cause the first pattern to be matched.
(#[$_meta:meta] $($remaining:tt)*) => {
WithoutId!($($remaining)*);
};
// This pattern is matched when there's no attributes.
($_vis:vis struct $($_tt:tt)*) => {
::std::compile_error!("`#[diesel(table_name = ...)]` is missing");
};
}
pub mod aggregates;
#[cfg(feature = "full")]
pub mod impls;

View file

@ -1,65 +0,0 @@
/// `macro_rules_attribute::derive(WithoutId!)` generates a variant of the struct with
/// `WithoutId` added to the name and no `id` field.
///
/// This is useful for making less redundant selections of multiple joined tables.
/// For example, selecting both `comment::post_id` and `post::id` is redundant if they
/// have the same value. In this case, the selection of `post::id` can be avoided by selecting
/// `PostWithoutId::as_select()` instead of `post::all_columns`.
///
/// This macro generates an `into_full` method, which converts to the sturct with `id`.
/// For example, `PostWithoutId` would have this:
///
/// `pub fn into_full(self, id: PostId) -> Post`
///
/// The `id` value can come from a column in another table, like `comment::post_id`.
///
/// The generated struct implements `Selectable` and `Queryable`.
macro_rules! WithoutId {
(
#[diesel(table_name = $table_name:ident)]
$(#[$_struct_meta:meta])*
$vis:vis struct $struct_name:ident {
$(#[$_id_meta:meta])*
$_id_vis:vis id: $id_type:ty,
$(
// TODO: more flexible and clean attribute matching
$(#[doc = $_doc1:tt])*
$(#[cfg($($cfgtt:tt)*)])*
$(#[cfg_attr($($cfgattrtt:tt)*)] $(#[doc = $_doc2:tt])*)*
$(#[serde($($serdett:tt)*)])*
$field_vis:vis $field_name:ident : $field_type:ty,
)*
}
) => {
::paste::paste! {
#[derive(::diesel::Queryable, ::diesel::Selectable)]
#[diesel(table_name = $table_name)]
$vis struct [<$struct_name WithoutId>] {
$(
$(#[cfg($($cfgtt)*)])*
$field_vis $field_name : $field_type,
)*
}
impl [<$struct_name WithoutId>] {
pub fn into_full(self, id: $id_type) -> $struct_name {
$struct_name {
id,
$($(#[cfg($($cfgtt)*)])* $field_name : self.$field_name,)*
}
}
}
}
};
// Keep on removing the first attribute until `diesel(table_name = ...)` becomes
// the first, which will cause the first pattern to be matched.
(#[$_meta:meta] $($remaining:tt)*) => {
WithoutId!($($remaining)*);
};
// This pattern is matched when there's no attributes.
($_vis:vis struct $($_tt:tt)*) => {
::std::compile_error!("`#[diesel(table_name = ...)]` is missing");
};
}