Adding a viewtovec trait.
authorDessalines <tyhou13@gmx.com>
Fri, 11 Dec 2020 01:39:42 +0000 (20:39 -0500)
committerDessalines <tyhou13@gmx.com>
Fri, 11 Dec 2020 01:39:42 +0000 (20:39 -0500)
lemmy_db/src/views/community_follower_view.rs
lemmy_db/src/views/community_moderator_view.rs
lemmy_db/src/views/community_view.rs
lemmy_db/src/views/mod.rs
lemmy_db/src/views/post_view.rs
lemmy_db/src/views/user_view.rs

index faded4dfc66f9e8b39dc16b89afc7f78c431f906..555a9bcd2387883db129d43878095f5cc3bbaa7e 100644 (file)
@@ -2,6 +2,7 @@ use crate::{
   community::{Community, CommunitySafe},
   schema::{community, community_follower, user_},
   user::{UserSafe, User_},
+  views::ViewToVec,
   ToSafe,
 };
 use diesel::{result::Error, *};
@@ -13,6 +14,8 @@ pub struct CommunityFollowerView {
   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
@@ -21,9 +24,9 @@ impl CommunityFollowerView {
       .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> {
@@ -33,18 +36,21 @@ impl CommunityFollowerView {
       .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>>()
+  }
 }
index 5cdcbf899d4695105591d954d32f8efb80841285..a2196ea3477974f16470393e4923b74b750dfafe 100644 (file)
@@ -2,6 +2,7 @@ use crate::{
   community::{Community, CommunitySafe},
   schema::{community, community_moderator, user_},
   user::{UserSafe, User_},
+  views::ViewToVec,
   ToSafe,
 };
 use diesel::{result::Error, *};
@@ -13,6 +14,8 @@ pub struct CommunityModeratorView {
   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
@@ -21,9 +24,9 @@ impl CommunityModeratorView {
       .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> {
@@ -33,18 +36,21 @@ impl CommunityModeratorView {
       .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>>()
+  }
 }
index 1ddbba64ff5f22aa69b3d0320408fb3e97775de1..0ac5081e6838d1ea472dd30179f57091862ef9e6 100644 (file)
@@ -7,6 +7,7 @@ use crate::{
   limit_and_offset,
   schema::{category, community, community_aggregates, community_follower, user_},
   user::{UserSafe, User_},
+  views::ViewToVec,
   MaybeOptional,
   SortType,
   ToSafe,
@@ -23,6 +24,14 @@ pub struct CommunityView {
   pub counts: CommunityAggregates,
 }
 
+type CommunityViewTuple = (
+  CommunitySafe,
+  UserSafe,
+  Category,
+  CommunityAggregates,
+  Option<CommunityFollower>,
+);
+
 impl CommunityView {
   pub fn read(
     conn: &PgConnection,
@@ -51,13 +60,7 @@ impl CommunityView {
         community_aggregates::all_columns,
         community_follower::all_columns.nullable(),
       ))
-      .first::<(
-        CommunitySafe,
-        UserSafe,
-        Category,
-        CommunityAggregates,
-        Option<CommunityFollower>,
-      )>(conn)?;
+      .first::<CommunityViewTuple>(conn)?;
 
     Ok(CommunityView {
       community,
@@ -270,35 +273,24 @@ impl<'a> CommunityQueryBuilder<'a> {
       .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>>()
+  }
 }
index a8112f0813cfcc5762a396b331d3f841721d39e8..465e5cffafa404e817f320d7819dcb57ccbeaf20 100644 (file)
@@ -5,3 +5,10 @@ pub mod community_view;
 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;
+}
index f7b6ac781dffbc963c56f58cf15570f87495b680..579a2b5d8d42ba907edf6984ee9ba4f60a9631b6 100644 (file)
@@ -17,6 +17,7 @@ use crate::{
     user_,
   },
   user::{UserSafe, User_},
+  views::ViewToVec,
   ListingType,
   MaybeOptional,
   SortType,
@@ -38,7 +39,7 @@ pub struct PostView {
   pub my_vote: Option<i16>,        // Left join to PostLike
 }
 
-type OutputTuple = (
+type PostViewTuple = (
   Post,
   UserSafe,
   CommunitySafe,
@@ -107,7 +108,7 @@ impl PostView {
           post_read::all_columns.nullable(),
           post_like::score.nullable(),
         ))
-        .first::<OutputTuple>(conn)?;
+        .first::<PostViewTuple>(conn)?;
 
     Ok(PostView {
       post,
@@ -551,26 +552,28 @@ impl<'a> PostQueryBuilder<'a> {
       .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>>()
+  }
 }
index 76bc3c3d33f776588328c0c3706b6c6fed127334..dae264097995b138ee442e52950cc7b3fbaa72e5 100644 (file)
@@ -4,6 +4,7 @@ use crate::{
   limit_and_offset,
   schema::{user_, user_aggregates},
   user::{UserSafe, User_},
+  views::ViewToVec,
   MaybeOptional,
   SortType,
   ToSafe,
@@ -17,18 +18,22 @@ pub struct UserViewSafe {
   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 })
   }
 }
@@ -39,7 +44,7 @@ impl UserViewSafe {
       .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 })
   }
 
@@ -49,9 +54,9 @@ impl UserViewSafe {
       .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> {
@@ -59,9 +64,9 @@ impl UserViewSafe {
       .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))
   }
 }
 
@@ -186,18 +191,21 @@ impl<'a> UserQueryBuilder<'a> {
     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>>()
+  }
 }