From dde4224debe46489dcba38c6974c455f11f21503 Mon Sep 17 00:00:00 2001
From: Paul Makles <paulmakles@gmail.com>
Date: Wed, 12 Aug 2020 16:13:42 +0200
Subject: [PATCH] Attach channels on guild object.

---
 src/database/guild.rs | 26 ++++++++++++++++++++++++++
 src/database/user.rs  | 21 ++++-----------------
 src/routes/guild.rs   | 31 +++----------------------------
 3 files changed, 33 insertions(+), 45 deletions(-)

diff --git a/src/database/guild.rs b/src/database/guild.rs
index b197cf3..02a297c 100644
--- a/src/database/guild.rs
+++ b/src/database/guild.rs
@@ -1,4 +1,5 @@
 use super::get_collection;
+use super::channel::Channel;
 
 use lru::LruCache;
 use mongodb::bson::{doc, from_bson, Bson};
@@ -164,6 +165,31 @@ pub fn fetch_guilds(ids: &Vec<String>) -> Result<Vec<Guild>, String> {
     }
 }
 
+pub fn serialise_guilds_with_channels(ids: &Vec<String>) -> Result<Vec<JsonValue>, String> {
+    let guilds = fetch_guilds(&gids)?;
+    let cids: Vec<String> = guilds
+        .iter()
+        .flat_map(|x| x.channels.clone())
+        .collect();
+
+    let channels = database::channel::fetch_channels(&cids)?;
+    let data: Vec<rocket_contrib::json::JsonValue> = guilds
+        .into_iter()
+        .map(|x| {
+            let id = x.id.clone();
+            let mut obj = x.serialise();
+            obj.as_object_mut().unwrap().insert(
+                "channels".to_string(),
+                channels.iter()
+                    .filter(|x| x.guild.is_some() && x.guild.as_ref().unwrap() == &id)
+                    .map(|x| x.clone().serialise())
+                    .collect()
+            );
+            obj
+        })
+        .collect()
+}
+
 pub fn fetch_member(key: MemberKey) -> Result<Option<Member>, String> {
     {
         if let Ok(mut cache) = MEMBER_CACHE.lock() {
diff --git a/src/database/user.rs b/src/database/user.rs
index 0dc8d95..3b5de3a 100644
--- a/src/database/user.rs
+++ b/src/database/user.rs
@@ -1,6 +1,6 @@
 use super::get_collection;
-use super::guild::{Guild, fetch_guilds};
-use super::channel::{Channel, fetch_channels};
+use super::guild::{serialise_guilds_with_channels};
+use super::channel::{fetch_channels};
 
 use lru::LruCache;
 use mongodb::bson::{doc, from_bson, Bson, DateTime};
@@ -130,29 +130,16 @@ impl User {
                 )
             })
             .collect();
-        
-        let guild_objects = fetch_guilds(&self.find_guilds()?)?;
-        let mut cids: Vec<String> = guild_objects
-            .iter()
-            .flat_map(|x| x.channels.clone())
-            .collect();
 
-        cids.append(&mut self.find_dms()?);
-
-        let channels: Vec<JsonValue> = fetch_channels(&cids)?
+        let channels: Vec<JsonValue> = fetch_channels(&self.find_dms()?)?
             .into_iter()
             .map(|x| x.serialise())
             .collect();
         
-        let guilds: Vec<JsonValue> = guild_objects
-            .into_iter()
-            .map(|x| x.serialise())
-            .collect();
-
         Ok(json!({
             "users": users,
             "channels": channels,
-            "guilds": guilds,
+            "guilds": serialise_guilds_with_channels(&self.find_guilds()?)?,
             "user": self.serialise(super::Relationship::SELF as i32)
         }))
     }
diff --git a/src/routes/guild.rs b/src/routes/guild.rs
index 1ce5392..9fe659b 100644
--- a/src/routes/guild.rs
+++ b/src/routes/guild.rs
@@ -2,7 +2,7 @@ use super::channel::ChannelType;
 use super::Response;
 use crate::database::guild::{fetch_member as get_member, get_invite, Guild, MemberKey};
 use crate::database::{
-    self, channel::fetch_channel, guild::fetch_guilds, channel::Channel, Permission, PermissionCalculator, user::User
+    self, channel::fetch_channel, guild::fetch_guilds, guild::serialise_guilds_with_channels, channel::Channel, Permission, PermissionCalculator, user::User
 };
 use crate::notifications::{
     self,
@@ -37,33 +37,8 @@ macro_rules! with_permissions {
 #[get("/@me")]
 pub fn my_guilds(user: User) -> Response {
     if let Ok(gids) = user.find_guilds() {
-        if let Ok(guilds) = fetch_guilds(&gids) {
-            let cids: Vec<String> = guilds
-                .iter()
-                .flat_map(|x| x.channels.clone())
-                .collect();
-
-            if let Ok(channels) = database::channel::fetch_channels(&cids) {
-                let data: Vec<rocket_contrib::json::JsonValue> = guilds
-                    .into_iter()
-                    .map(|x| {
-                        let id = x.id.clone();
-                        let mut obj = x.serialise();
-                        obj.as_object_mut().unwrap().insert(
-                            "channels".to_string(),
-                            channels.iter()
-                                .filter(|x| x.guild.is_some() && x.guild.as_ref().unwrap() == &id)
-                                .map(|x| x.clone().serialise())
-                                .collect()
-                        );
-                        obj
-                    })
-                    .collect();
-                
-                Response::Success(json!(data))
-            } else {
-                Response::InternalServerError(json!({ "error": "Failed to fetch channels." }))
-            }
+        if let Ok(data) = serialise_guilds_with_channels(&gids) {
+            Response::Success(data)
         } else {
             Response::InternalServerError(json!({ "error": "Failed to fetch guilds." }))
         }
-- 
GitLab