community::{Community, CommunitySafe},
schema::{community, community_follower, user_},
user::{UserSafe, User_},
+ views::ViewToVec,
ToSafe,
};
use diesel::{result::Error, *};
pub follower: UserSafe,
}
+type CommunityFollowerViewTuple = (CommunitySafe, UserSafe);
+
impl CommunityFollowerView {
pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
let res = community_follower::table
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
.filter(community_follower::community_id.eq(for_community_id))
.order_by(community_follower::published)
- .load::<(CommunitySafe, UserSafe)>(conn)?;
+ .load::<CommunityFollowerViewTuple>(conn)?;
- Ok(to_vec(res))
+ Ok(Self::to_vec(res))
}
pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
.filter(community_follower::user_id.eq(for_user_id))
.order_by(community_follower::published)
- .load::<(CommunitySafe, UserSafe)>(conn)?;
+ .load::<CommunityFollowerViewTuple>(conn)?;
- Ok(to_vec(res))
+ Ok(Self::to_vec(res))
}
}
-fn to_vec(users: Vec<(CommunitySafe, UserSafe)>) -> Vec<CommunityFollowerView> {
- users
- .iter()
- .map(|a| CommunityFollowerView {
- community: a.0.to_owned(),
- follower: a.1.to_owned(),
- })
- .collect::<Vec<CommunityFollowerView>>()
+impl ViewToVec for CommunityFollowerView {
+ type DbTuple = CommunityFollowerViewTuple;
+ fn to_vec(users: Vec<Self::DbTuple>) -> Vec<Self> {
+ users
+ .iter()
+ .map(|a| Self {
+ community: a.0.to_owned(),
+ follower: a.1.to_owned(),
+ })
+ .collect::<Vec<Self>>()
+ }
}
community::{Community, CommunitySafe},
schema::{community, community_moderator, user_},
user::{UserSafe, User_},
+ views::ViewToVec,
ToSafe,
};
use diesel::{result::Error, *};
pub moderator: UserSafe,
}
+type CommunityModeratorViewTuple = (CommunitySafe, UserSafe);
+
impl CommunityModeratorView {
pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
let res = community_moderator::table
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
.filter(community_moderator::community_id.eq(for_community_id))
.order_by(community_moderator::published)
- .load::<(CommunitySafe, UserSafe)>(conn)?;
+ .load::<CommunityModeratorViewTuple>(conn)?;
- Ok(to_vec(res))
+ Ok(Self::to_vec(res))
}
pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
.select((Community::safe_columns_tuple(), User_::safe_columns_tuple()))
.filter(community_moderator::user_id.eq(for_user_id))
.order_by(community_moderator::published)
- .load::<(CommunitySafe, UserSafe)>(conn)?;
+ .load::<CommunityModeratorViewTuple>(conn)?;
- Ok(to_vec(res))
+ Ok(Self::to_vec(res))
}
}
-fn to_vec(users: Vec<(CommunitySafe, UserSafe)>) -> Vec<CommunityModeratorView> {
- users
- .iter()
- .map(|a| CommunityModeratorView {
- community: a.0.to_owned(),
- moderator: a.1.to_owned(),
- })
- .collect::<Vec<CommunityModeratorView>>()
+impl ViewToVec for CommunityModeratorView {
+ type DbTuple = CommunityModeratorViewTuple;
+ fn to_vec(community_moderators: Vec<Self::DbTuple>) -> Vec<Self> {
+ community_moderators
+ .iter()
+ .map(|a| Self {
+ community: a.0.to_owned(),
+ moderator: a.1.to_owned(),
+ })
+ .collect::<Vec<Self>>()
+ }
}
limit_and_offset,
schema::{category, community, community_aggregates, community_follower, user_},
user::{UserSafe, User_},
+ views::ViewToVec,
MaybeOptional,
SortType,
ToSafe,
pub counts: CommunityAggregates,
}
+type CommunityViewTuple = (
+ CommunitySafe,
+ UserSafe,
+ Category,
+ CommunityAggregates,
+ Option<CommunityFollower>,
+);
+
impl CommunityView {
pub fn read(
conn: &PgConnection,
community_aggregates::all_columns,
community_follower::all_columns.nullable(),
))
- .first::<(
- CommunitySafe,
- UserSafe,
- Category,
- CommunityAggregates,
- Option<CommunityFollower>,
- )>(conn)?;
+ .first::<CommunityViewTuple>(conn)?;
Ok(CommunityView {
community,
.offset(offset)
.filter(community::removed.eq(false))
.filter(community::deleted.eq(false))
- .load::<(
- CommunitySafe,
- UserSafe,
- Category,
- CommunityAggregates,
- Option<CommunityFollower>,
- )>(self.conn)?;
+ .load::<CommunityViewTuple>(self.conn)?;
- Ok(to_vec(res))
+ Ok(CommunityView::to_vec(res))
}
}
-fn to_vec(
- users: Vec<(
- CommunitySafe,
- UserSafe,
- Category,
- CommunityAggregates,
- Option<CommunityFollower>,
- )>,
-) -> Vec<CommunityView> {
- users
- .iter()
- .map(|a| CommunityView {
- community: a.0.to_owned(),
- creator: a.1.to_owned(),
- category: a.2.to_owned(),
- counts: a.3.to_owned(),
- subscribed: a.4.is_some(),
- })
- .collect::<Vec<CommunityView>>()
+impl ViewToVec for CommunityView {
+ type DbTuple = CommunityViewTuple;
+ fn to_vec(communities: Vec<Self::DbTuple>) -> Vec<Self> {
+ communities
+ .iter()
+ .map(|a| Self {
+ community: a.0.to_owned(),
+ creator: a.1.to_owned(),
+ category: a.2.to_owned(),
+ counts: a.3.to_owned(),
+ subscribed: a.4.is_some(),
+ })
+ .collect::<Vec<Self>>()
+ }
}
pub mod post_view;
pub mod site_view;
pub mod user_view;
+
+pub(crate) trait ViewToVec {
+ type DbTuple;
+ fn to_vec(tuple: Vec<Self::DbTuple>) -> Vec<Self>
+ where
+ Self: Sized;
+}
user_,
},
user::{UserSafe, User_},
+ views::ViewToVec,
ListingType,
MaybeOptional,
SortType,
pub my_vote: Option<i16>, // Left join to PostLike
}
-type OutputTuple = (
+type PostViewTuple = (
Post,
UserSafe,
CommunitySafe,
post_read::all_columns.nullable(),
post_like::score.nullable(),
))
- .first::<OutputTuple>(conn)?;
+ .first::<PostViewTuple>(conn)?;
Ok(PostView {
post,
.filter(post::deleted.eq(false))
.filter(community::removed.eq(false))
.filter(community::deleted.eq(false))
- .load::<OutputTuple>(self.conn)?;
+ .load::<PostViewTuple>(self.conn)?;
- Ok(to_vec(res))
+ Ok(PostView::to_vec(res))
}
}
-// TODO turn this into a trait with an associated type
-fn to_vec(posts: Vec<OutputTuple>) -> Vec<PostView> {
- posts
- .iter()
- .map(|a| PostView {
- post: a.0.to_owned(),
- creator: a.1.to_owned(),
- community: a.2.to_owned(),
- counts: a.3.to_owned(),
- subscribed: a.4.is_some(),
- banned_from_community: a.5.is_some(),
- saved: a.6.is_some(),
- read: a.7.is_some(),
- my_vote: a.8,
- })
- .collect::<Vec<PostView>>()
+impl ViewToVec for PostView {
+ type DbTuple = PostViewTuple;
+ fn to_vec(posts: Vec<Self::DbTuple>) -> Vec<Self> {
+ posts
+ .iter()
+ .map(|a| Self {
+ post: a.0.to_owned(),
+ creator: a.1.to_owned(),
+ community: a.2.to_owned(),
+ counts: a.3.to_owned(),
+ subscribed: a.4.is_some(),
+ banned_from_community: a.5.is_some(),
+ saved: a.6.is_some(),
+ read: a.7.is_some(),
+ my_vote: a.8,
+ })
+ .collect::<Vec<Self>>()
+ }
}
limit_and_offset,
schema::{user_, user_aggregates},
user::{UserSafe, User_},
+ views::ViewToVec,
MaybeOptional,
SortType,
ToSafe,
pub counts: UserAggregates,
}
+type UserViewSafeTuple = (UserSafe, UserAggregates);
+
#[derive(Debug, Serialize, Clone)]
pub struct UserViewDangerous {
pub user: User_,
pub counts: UserAggregates,
}
+type UserViewDangerousTuple = (User_, UserAggregates);
+
impl UserViewDangerous {
pub fn read(conn: &PgConnection, id: i32) -> Result<Self, Error> {
let (user, counts) = user_::table
.find(id)
.inner_join(user_aggregates::table)
- .first::<(User_, UserAggregates)>(conn)?;
+ .first::<UserViewDangerousTuple>(conn)?;
Ok(Self { user, counts })
}
}
.find(id)
.inner_join(user_aggregates::table)
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
- .first::<(UserSafe, UserAggregates)>(conn)?;
+ .first::<UserViewSafeTuple>(conn)?;
Ok(Self { user, counts })
}
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
.filter(user_::admin.eq(true))
.order_by(user_::published)
- .load::<(UserSafe, UserAggregates)>(conn)?;
+ .load::<UserViewSafeTuple>(conn)?;
- Ok(to_vec(admins))
+ Ok(Self::to_vec(admins))
}
pub fn banned(conn: &PgConnection) -> Result<Vec<Self>, Error> {
.inner_join(user_aggregates::table)
.select((User_::safe_columns_tuple(), user_aggregates::all_columns))
.filter(user_::banned.eq(true))
- .load::<(UserSafe, UserAggregates)>(conn)?;
+ .load::<UserViewSafeTuple>(conn)?;
- Ok(to_vec(banned))
+ Ok(Self::to_vec(banned))
}
}
let (limit, offset) = limit_and_offset(self.page, self.limit);
query = query.limit(limit).offset(offset);
- let res = query.load::<(UserSafe, UserAggregates)>(self.conn)?;
+ let res = query.load::<UserViewSafeTuple>(self.conn)?;
- Ok(to_vec(res))
+ Ok(UserViewSafe::to_vec(res))
}
}
-fn to_vec(users: Vec<(UserSafe, UserAggregates)>) -> Vec<UserViewSafe> {
- users
- .iter()
- .map(|a| UserViewSafe {
- user: a.0.to_owned(),
- counts: a.1.to_owned(),
- })
- .collect::<Vec<UserViewSafe>>()
+impl ViewToVec for UserViewSafe {
+ type DbTuple = UserViewSafeTuple;
+ fn to_vec(users: Vec<Self::DbTuple>) -> Vec<Self> {
+ users
+ .iter()
+ .map(|a| Self {
+ user: a.0.to_owned(),
+ counts: a.1.to_owned(),
+ })
+ .collect::<Vec<Self>>()
+ }
}