summaryrefslogtreecommitdiffstats
path: root/server/src/api/community.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/api/community.rs')
-rw-r--r--server/src/api/community.rs387
1 files changed, 229 insertions, 158 deletions
diff --git a/server/src/api/community.rs b/server/src/api/community.rs
index 3fc67eb3..02071c57 100644
--- a/server/src/api/community.rs
+++ b/server/src/api/community.rs
@@ -7,6 +7,7 @@ use crate::{
ActorType,
EndpointType,
},
+ blocking,
db::{Bannable, Crud, Followable, Joinable, SortType},
is_valid_community_name,
naive_from_unix,
@@ -18,12 +19,9 @@ use crate::{
UserOperation,
WebsocketInfo,
},
+ DbPool,
+ LemmyError,
};
-use diesel::{
- r2d2::{ConnectionManager, Pool},
- PgConnection,
-};
-use failure::Error;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
@@ -138,14 +136,15 @@ pub struct TransferCommunity {
auth: String,
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<GetCommunity> {
type Response = GetCommunityResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
websocket_info: Option<WebsocketInfo>,
- ) -> Result<GetCommunityResponse, Error> {
+ ) -> Result<GetCommunityResponse, LemmyError> {
let data: &GetCommunity = &self.data;
let user_id: Option<i32> = match &data.auth {
@@ -159,33 +158,38 @@ impl Perform for Oper<GetCommunity> {
None => None,
};
- let conn = pool.get()?;
-
+ let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
let community = match data.id {
- Some(id) => Community::read(&conn, id)?,
- None => {
- match Community::read_from_name(
- &conn,
- &data.name.to_owned().unwrap_or_else(|| "main".to_string()),
- ) {
- Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
- }
- }
+ Some(id) => blocking(pool, move |conn| Community::read(conn, id)).await??,
+ None => match blocking(pool, move |conn| Community::read_from_name(conn, &name)).await? {
+ Ok(community) => community,
+ Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
+ },
};
- let community_view = match CommunityView::read(&conn, community.id, user_id) {
+ let community_id = community.id;
+ let community_view = match blocking(pool, move |conn| {
+ CommunityView::read(conn, community_id, user_id)
+ })
+ .await?
+ {
Ok(community) => community,
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};
- let moderators = match CommunityModeratorView::for_community(&conn, community.id) {
+ let community_id = community.id;
+ let moderators: Vec<CommunityModeratorView> = match blocking(pool, move |conn| {
+ CommunityModeratorView::for_community(conn, community_id)
+ })
+ .await?
+ {
Ok(moderators) => moderators,
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};
- let site_creator_id = Site::read(&conn, 1)?.creator_id;
- let mut admins = UserView::admins(&conn)?;
+ let site = blocking(pool, move |conn| Site::read(conn, 1)).await??;
+ let site_creator_id = site.creator_id;
+ let mut admins = blocking(pool, move |conn| UserView::admins(conn)).await??;
let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
let creator_user = admins.remove(creator_index);
admins.insert(0, creator_user);
@@ -220,14 +224,15 @@ impl Perform for Oper<GetCommunity> {
}
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<CreateCommunity> {
type Response = CommunityResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
_websocket_info: Option<WebsocketInfo>,
- ) -> Result<CommunityResponse, Error> {
+ ) -> Result<CommunityResponse, LemmyError> {
let data: &CreateCommunity = &self.data;
let claims = match Claims::decode(&data.auth) {
@@ -255,10 +260,9 @@ impl Perform for Oper<CreateCommunity> {
let user_id = claims.id;
- let conn = pool.get()?;
-
// Check for a site ban
- if UserView::read(&conn, user_id)?.banned {
+ let user_view = blocking(pool, move |conn| UserView::read(conn, user_id)).await??;
+ if user_view.banned {
return Err(APIError::err("site_ban").into());
}
@@ -283,34 +287,36 @@ impl Perform for Oper<CreateCommunity> {
published: None,
};
- let inserted_community = match Community::create(&conn, &community_form) {
- Ok(community) => community,
- Err(_e) => return Err(APIError::err("community_already_exists").into()),
- };
+ let inserted_community =
+ match blocking(pool, move |conn| Community::create(conn, &community_form)).await? {
+ Ok(community) => community,
+ Err(_e) => return Err(APIError::err("community_already_exists").into()),
+ };
let community_moderator_form = CommunityModeratorForm {
community_id: inserted_community.id,
user_id,
};
- let _inserted_community_moderator =
- match CommunityModerator::join(&conn, &community_moderator_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
- };
+ let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
+ if blocking(pool, join).await?.is_err() {
+ return Err(APIError::err("community_moderator_already_exists").into());
+ }
let community_follower_form = CommunityFollowerForm {
community_id: inserted_community.id,
user_id,
};
- let _inserted_community_follower =
- match CommunityFollower::follow(&conn, &community_follower_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
- };
+ let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
+ if blocking(pool, follow).await?.is_err() {
+ return Err(APIError::err("community_follower_already_exists").into());
+ }
- let community_view = CommunityView::read(&conn, inserted_community.id, Some(user_id))?;
+ let community_view = blocking(pool, move |conn| {
+ CommunityView::read(conn, inserted_community.id, Some(user_id))
+ })
+ .await??;
Ok(CommunityResponse {
community: community_view,
@@ -318,14 +324,15 @@ impl Perform for Oper<CreateCommunity> {
}
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<EditCommunity> {
type Response = CommunityResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
websocket_info: Option<WebsocketInfo>,
- ) -> Result<CommunityResponse, Error> {
+ ) -> Result<CommunityResponse, LemmyError> {
let data: &EditCommunity = &self.data;
if let Err(slurs) = slur_check(&data.name) {
@@ -353,28 +360,34 @@ impl Perform for Oper<EditCommunity> {
let user_id = claims.id;
- let conn = pool.get()?;
-
// Check for a site ban
- let user = User_::read(&conn, user_id)?;
+ let user = blocking(pool, move |conn| User_::read(conn, user_id)).await??;
if user.banned {
return Err(APIError::err("site_ban").into());
}
// Verify its a mod
+ let edit_id = data.edit_id;
let mut editors: Vec<i32> = Vec::new();
editors.append(
- &mut CommunityModeratorView::for_community(&conn, data.edit_id)?
- .into_iter()
- .map(|m| m.user_id)
- .collect(),
+ &mut blocking(pool, move |conn| {
+ CommunityModeratorView::for_community(conn, edit_id)
+ .map(|v| v.into_iter().map(|m| m.user_id).collect())
+ })
+ .await??,
+ );
+ editors.append(
+ &mut blocking(pool, move |conn| {
+ UserView::admins(conn).map(|v| v.into_iter().map(|a| a.id).collect())
+ })
+ .await??,
);
- editors.append(&mut UserView::admins(&conn)?.into_iter().map(|a| a.id).collect());
if !editors.contains(&user_id) {
return Err(APIError::err("no_community_edit_allowed").into());
}
- let read_community = Community::read(&conn, data.edit_id)?;
+ let edit_id = data.edit_id;
+ let read_community = blocking(pool, move |conn| Community::read(conn, edit_id)).await??;
let community_form = CommunityForm {
name: data.name.to_owned(),
@@ -394,7 +407,12 @@ impl Perform for Oper<EditCommunity> {
published: None,
};
- let updated_community = match Community::update(&conn, data.edit_id, &community_form) {
+ let edit_id = data.edit_id;
+ let updated_community = match blocking(pool, move |conn| {
+ Community::update(conn, edit_id, &community_form)
+ })
+ .await?
+ {
Ok(community) => community,
Err(_e) => return Err(APIError::err("couldnt_update_community").into()),
};
@@ -412,24 +430,36 @@ impl Perform for Oper<EditCommunity> {
reason: data.reason.to_owned(),
expires,
};
- ModRemoveCommunity::create(&conn, &form)?;
+ blocking(pool, move |conn| ModRemoveCommunity::create(conn, &form)).await??;
}
if let Some(deleted) = data.deleted.to_owned() {
if deleted {
- updated_community.send_delete(&user, &conn)?;
+ updated_community
+ .send_delete(&user, &self.client, pool)
+ .await?;
} else {
- updated_community.send_undo_delete(&user, &conn)?;
+ updated_community
+ .send_undo_delete(&user, &self.client, pool)
+ .await?;
}
} else if let Some(removed) = data.removed.to_owned() {
if removed {
- updated_community.send_remove(&user, &conn)?;
+ updated_community
+ .send_remove(&user, &self.client, pool)
+ .await?;
} else {
- updated_community.send_undo_remove(&user, &conn)?;
+ updated_community
+ .send_undo_remove(&user, &self.client, pool)
+ .await?;
}
}
- let community_view = CommunityView::read(&conn, data.edit_id, Some(user_id))?;
+ let edit_id = data.edit_id;
+ let community_view = blocking(pool, move |conn| {
+ CommunityView::read(conn, edit_id, Some(user_id))
+ })
+ .await??;
let res = CommunityResponse {
community: community_view,
@@ -453,14 +483,15 @@ impl Perform for Oper<EditCommunity> {
}
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<ListCommunities> {
type Response = ListCommunitiesResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
_websocket_info: Option<WebsocketInfo>,
- ) -> Result<ListCommunitiesResponse, Error> {
+ ) -> Result<ListCommunitiesResponse, LemmyError> {
let data: &ListCommunities = &self.data;
let user_claims: Option<Claims> = match &data.auth {
@@ -483,29 +514,33 @@ impl Perform for Oper<ListCommunities> {
let sort = SortType::from_str(&data.sort)?;
- let conn = pool.get()?;
-
- let communities = CommunityQueryBuilder::create(&conn)
- .sort(&sort)
- .for_user(user_id)
- .show_nsfw(show_nsfw)
- .page(data.page)
- .limit(data.limit)
- .list()?;
+ let page = data.page;
+ let limit = data.limit;
+ let communities = blocking(pool, move |conn| {
+ CommunityQueryBuilder::create(conn)
+ .sort(&sort)
+ .for_user(user_id)
+ .show_nsfw(show_nsfw)
+ .page(page)
+ .limit(limit)
+ .list()
+ })
+ .await??;
// Return the jwt
Ok(ListCommunitiesResponse { communities })
}
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<FollowCommunity> {
type Response = CommunityResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
_websocket_info: Option<WebsocketInfo>,
- ) -> Result<CommunityResponse, Error> {
+ ) -> Result<CommunityResponse, LemmyError> {
let data: &FollowCommunity = &self.data;
let claims = match Claims::decode(&data.auth) {
@@ -515,9 +550,8 @@ impl Perform for Oper<FollowCommunity> {
let user_id = claims.id;
- let conn = pool.get()?;
-
- let community = Community::read(&conn, data.community_id)?;
+ let community_id = data.community_id;
+ let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
let community_follower_form = CommunityFollowerForm {
community_id: data.community_id,
user_id,
@@ -525,34 +559,44 @@ impl Perform for Oper<FollowCommunity> {
if community.local {
if data.follow {
- match CommunityFollower::follow(&conn, &community_follower_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
- };
+ let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
+ if blocking(pool, follow).await?.is_err() {
+ return Err(APIError::err("community_follower_already_exists").into());
+ }
} else {
- match CommunityFollower::unfollow(&conn, &community_follower_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
- };
+ let unfollow =
+ move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
+ if blocking(pool, unfollow).await?.is_err() {
+ return Err(APIError::err("community_follower_already_exists").into());
+ }
}
} else {
- let user = User_::read(&conn, user_id)?;
+ let user = blocking(pool, move |conn| User_::read(conn, user_id)).await??;
if data.follow {
// Dont actually add to the community followers here, because you need
// to wait for the accept
- user.send_follow(&community.actor_id, &conn)?;
+ user
+ .send_follow(&community.actor_id, &self.client, pool)
+ .await?;
} else {
- user.send_unfollow(&community.actor_id, &conn)?;
- match CommunityFollower::unfollow(&conn, &community_follower_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
- };
+ user
+ .send_unfollow(&community.actor_id, &self.client, pool)
+ .await?;
+ let unfollow =
+ move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
+ if blocking(pool, unfollow).await?.is_err() {
+ return Err(APIError::err("community_follower_already_exists").into());
+ }
}
// TODO: this needs to return a "pending" state, until Accept is received from the remote server
}
- let community_view = CommunityView::read(&conn, data.community_id, Some(user_id))?;
+ let community_id = data.community_id;
+ let community_view = blocking(pool, move |conn| {
+ CommunityView::read(conn, community_id, Some(user_id))
+ })
+ .await??;
Ok(CommunityResponse {
community: community_view,
@@ -560,14 +604,15 @@ impl Perform for Oper<FollowCommunity> {
}
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<GetFollowedCommunities> {
type Response = GetFollowedCommunitiesResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
_websocket_info: Option<WebsocketInfo>,
- ) -> Result<GetFollowedCommunitiesResponse, Error> {
+ ) -> Result<GetFollowedCommunitiesResponse, LemmyError> {
let data: &GetFollowedCommunities = &self.data;
let claims = match Claims::decode(&data.auth) {
@@ -577,27 +622,29 @@ impl Perform for Oper<GetFollowedCommunities> {
let user_id = claims.id;
- let conn = pool.get()?;
-
- let communities: Vec<CommunityFollowerView> =
- match CommunityFollowerView::for_user(&conn, user_id) {
- Ok(communities) => communities,
- Err(_e) => return Err(APIError::err("system_err_login").into()),
- };
+ let communities = match blocking(pool, move |conn| {
+ CommunityFollowerView::for_user(conn, user_id)
+ })
+ .await?
+ {
+ Ok(communities) => communities,
+ _ => return Err(APIError::err("system_err_login").into()),
+ };
// Return the jwt
Ok(GetFollowedCommunitiesResponse { communities })
}
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<BanFromCommunity> {
type Response = BanFromCommunityResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
websocket_info: Option<WebsocketInfo>,
- ) -> Result<BanFromCommunityResponse, Error> {
+ ) -> Result<BanFromCommunityResponse, LemmyError> {
let data: &BanFromCommunity = &self.data;
let claims = match Claims::decode(&data.auth) {
@@ -612,18 +659,16 @@ impl Perform for Oper<BanFromCommunity> {
user_id: data.user_id,
};
- let conn = pool.get()?;
-
if data.ban {
- match CommunityUserBan::ban(&conn, &community_user_ban_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_user_already_banned").into()),
- };
+ let ban = move |conn: &'_ _| CommunityUserBan::ban(conn, &community_user_ban_form);
+ if blocking(pool, ban).await?.is_err() {
+ return Err(APIError::err("community_user_already_banned").into());
+ }
} else {
- match CommunityUserBan::unban(&conn, &community_user_ban_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_user_already_banned").into()),
- };
+ let unban = move |conn: &'_ _| CommunityUserBan::unban(conn, &community_user_ban_form);
+ if blocking(pool, unban).await?.is_err() {
+ return Err(APIError::err("community_user_already_banned").into());
+ }
}
// Mod tables
@@ -640,9 +685,10 @@ impl Perform for Oper<BanFromCommunity> {
banned: Some(data.ban),
expires,
};
- ModBanFromCommunity::create(&conn, &form)?;
+ blocking(pool, move |conn| ModBanFromCommunity::create(conn, &form)).await??;
- let user_view = UserView::read(&conn, data.user_id)?;
+ let user_id = data.user_id;
+ let user_view = blocking(pool, move |conn| UserView::read(conn, user_id)).await??;
let res = BanFromCommunityResponse {
user: user_view,
@@ -662,14 +708,15 @@ impl Perform for Oper<BanFromCommunity> {
}
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<AddModToCommunity> {
type Response = AddModToCommunityResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
websocket_info: Option<WebsocketInfo>,
- ) -> Result<AddModToCommunityResponse, Error> {
+ ) -> Result<AddModToCommunityResponse, LemmyError> {
let data: &AddModToCommunity = &self.data;
let claims = match Claims::decode(&data.auth) {
@@ -684,18 +731,16 @@ impl Perform for Oper<AddModToCommunity> {
user_id: data.user_id,
};
- let conn = pool.get()?;
-
if data.added {
- match CommunityModerator::join(&conn, &community_moderator_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
- };
+ let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
+ if blocking(pool, join).await?.is_err() {
+ return Err(APIError::err("community_moderator_already_exists").into());
+ }
} else {
- match CommunityModerator::leave(&conn, &community_moderator_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
- };
+ let leave = move |conn: &'_ _| CommunityModerator::leave(conn, &community_moderator_form);
+ if blocking(pool, leave).await?.is_err() {
+ return Err(APIError::err("community_moderator_already_exists").into());
+ }
}
// Mod tables
@@ -705,9 +750,13 @@ impl Perform for Oper<AddModToCommunity> {
community_id: data.community_id,
removed: Some(!data.added),
};
- ModAddCommunity::create(&conn, &form)?;
+ blocking(pool, move |conn| ModAddCommunity::create(conn, &form)).await??;
- let moderators = CommunityModeratorView::for_community(&conn, data.community_id)?;
+ let community_id = data.community_id;
+ let moderators = blocking(pool, move |conn| {
+ CommunityModeratorView::for_community(conn, community_id)
+ })
+ .await??;
let res = AddModToCommunityResponse { moderators };
@@ -724,14 +773,15 @@ impl Perform for Oper<AddModToCommunity> {
}
}
+#[async_trait::async_trait(?Send)]
impl Perform for Oper<TransferCommunity> {
type Response = GetCommunityResponse;
- fn perform(
+ async fn perform(
&self,
- pool: Pool<ConnectionManager<PgConnection>>,
+ pool: &DbPool,
_websocket_info: Option<WebsocketInfo>,
- ) -> Result<GetCommunityResponse, Error> {
+ ) -> Result<GetCommunityResponse, LemmyError> {
let data: &TransferCommunity = &self.data;
let claims = match Claims::decode(&data.auth) {
@@ -741,12 +791,14 @@ impl Perform for Oper<TransferCommunity> {
let user_id = claims.id;
- let conn = pool.get()?;
+ let community_id = data.community_id;
+ let read_community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
+
+ let site_creator_id =
+ blocking(pool, move |conn| Site::read(conn, 1).map(|s| s.creator_id)).await??;
- let read_community = Community::read(&conn, data.community_id)?;
+ let mut admins = blocking(pool, move |conn| UserView::admins(conn)).await??;
- let site_creator_id = Site::read(&conn, 1)?.creator_id;
- let mut admins = UserView::admins(&conn)?;
let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
let creator_user = admins.remove(creator_index);
admins.insert(0, creator_user);
@@ -774,13 +826,18 @@ impl Perform for Oper<TransferCommunity> {
published: None,
};
- let _updated_community = match Community::update(&conn, data.community_id, &community_form) {
- Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_update_community").into()),
+ let community_id = data.community_id;
+ let update = move |conn: &'_ _| Community::update(conn, community_id, &community_form);
+ if blocking(pool, update).await?.is_err() {
+ return Err(APIError::err("couldnt_update_community").into());
};
// You also have to re-do the community_moderator table, reordering it.
- let mut community_mods = CommunityModeratorView::for_community(&conn, data.community_id)?;
+ let community_id = data.community_id;
+ let mut community_mods = blocking(pool, move |conn| {
+ CommunityModeratorView::for_community(conn, community_id)
+ })
+ .await??;
let creator_index = community_mods
.iter()
.position(|r| r.user_id == data.user_id)
@@ -788,19 +845,23 @@ impl Perform for Oper<TransferCommunity> {
let creator_user = community_mods.remove(creator_index);
community_mods.insert(0, creator_user);
- CommunityModerator::delete_for_community(&conn, data.community_id)?;
+ let community_id = data.community_id;
+ blocking(pool, move |conn| {
+ CommunityModerator::delete_for_community(conn, community_id)
+ })
+ .await??;
+ // TODO: this should probably be a bulk operation
for cmod in &community_mods {
let community_moderator_form = CommunityModeratorForm {
community_id: cmod.community_id,
user_id: cmod.user_id,
};
- let _inserted_community_moderator =
- match CommunityModerator::join(&conn, &community_moderator_form) {
- Ok(user) => user,
- Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
- };
+ let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
+ if blocking(pool, join).await?.is_err() {
+ return Err(APIError::err("community_moderator_already_exists").into());
+ }
}
// Mod tables
@@ -810,14 +871,24 @@ impl Perform for Oper<TransferCommunity> {
community_id: data.community_id,
removed: Some(false),
};
- ModAddCommunity::create(&conn, &form)?;
+ blocking(pool, move |conn| ModAddCommunity::create(conn, &form)).await??;
- let community_view = match CommunityView::read(&conn, data.community_id, Some(user_id)) {
+ let community_id = data.community_id;
+ let community_view = match blocking(pool, move |conn| {
+ CommunityView::read(conn, community_id, Some(user_id))
+ })
+ .await?
+ {
Ok(community) => community,
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};
- let moderators = match CommunityModeratorView::for_community(&conn, data.community_id) {
+ let community_id = data.community_id;
+ let moderators = match blocking(pool, move |conn| {
+ CommunityModeratorView::for_community(conn, community_id)
+ })
+ .await?
+ {
Ok(moderators) => moderators,
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};