From 222a417fff3f8e60ce2b1ed6419e9c881b09261b Mon Sep 17 00:00:00 2001
From: Paul Makles <paulmakles@gmail.com>
Date: Tue, 26 Jan 2021 22:33:14 +0000
Subject: [PATCH] Add utility function for including relationship on User.

---
 src/database/entities/user.rs  | 18 ++++++++++++++++++
 src/notifications/payload.rs   | 21 ++++++++-------------
 src/routes/users/fetch_user.rs | 22 ++++++----------------
 3 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/src/database/entities/user.rs b/src/database/entities/user.rs
index 778c024..26f6b77 100644
--- a/src/database/entities/user.rs
+++ b/src/database/entities/user.rs
@@ -36,6 +36,24 @@ pub struct User {
 }
 
 impl User {
+    /// Mutate the user object to include relationship as seen by user.
+    pub fn from(mut self, user: &User) -> User {
+        if self.id == user.id {
+            self.relationship = Some(RelationshipStatus::User);
+            return self;
+        }
+
+        if let Some(relations) = &user.relations {
+            if let Some(relationship) = relations.iter().find(|x| self.id == x.id) {
+                self.relationship = Some(relationship.status.clone());
+                return self;
+            }
+        }
+
+        self
+    }
+
+    /// Mutate the user object to appear as seen by user.
     pub fn with(mut self, permissions: UserPermissions<[u32; 1]>) -> User {
         if !permissions.get_view_all() {
             self.relations = None;
diff --git a/src/notifications/payload.rs b/src/notifications/payload.rs
index c81b958..b9570dc 100644
--- a/src/notifications/payload.rs
+++ b/src/notifications/payload.rs
@@ -65,6 +65,7 @@ pub async fn generate_ready(mut user: User) -> Result<ClientboundNotification> {
         }
     }
 
+    user_ids.remove(&user.id);
     if user_ids.len() > 0 {
         let mut cursor = get_collection("users")
             .find(
@@ -85,33 +86,27 @@ pub async fn generate_ready(mut user: User) -> Result<ClientboundNotification> {
 
         while let Some(result) = cursor.next().await {
             if let Ok(doc) = result {
-                let mut other: User = from_document(doc).map_err(|_| Error::DatabaseError {
+                let other: User = from_document(doc).map_err(|_| Error::DatabaseError {
                     operation: "from_document",
                     with: "user",
                 })?;
 
-                if let Some(relationships) = &user.relations {
-                    other.relationship = Some(
-                        if let Some(relationship) = relationships.iter().find(|x| other.id == x.id)
-                        {
-                            relationship.status.clone()
-                        } else {
-                            RelationshipStatus::None
-                        },
-                    );
-                }
-
                 let permissions = PermissionCalculator::new(&user)
                     .with_mutual_connection()
                     .with_user(&other)
                     .for_user_given()
                     .await?;
 
-                users.push(other.with(permissions));
+                users.push(
+                    other
+                        .from(&user)
+                        .with(permissions)
+                );
             }
         }
     }
 
+    user.relationship = Some(RelationshipStatus::User);
     user.online = Some(true);
     users.push(user);
 
diff --git a/src/routes/users/fetch_user.rs b/src/routes/users/fetch_user.rs
index f2731f8..0ca10a4 100644
--- a/src/routes/users/fetch_user.rs
+++ b/src/routes/users/fetch_user.rs
@@ -5,7 +5,7 @@ use rocket_contrib::json::JsonValue;
 
 #[get("/<target>")]
 pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
-    let mut target = target.fetch_user().await?;
+    let target = target.fetch_user().await?;
 
     let perm = permissions::PermissionCalculator::new(&user)
         .with_user(&target)
@@ -16,19 +16,9 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
         Err(Error::LabelMe)?
     }
 
-    if user.id != target.id {
-        if let Some(relationships) = &user.relations {
-            target.relationship = relationships
-                .iter()
-                .find(|x| x.id == user.id)
-                .map(|x| x.status.clone())
-                .or_else(|| Some(RelationshipStatus::None));
-        } else {
-            target.relationship = Some(RelationshipStatus::None);
-        }
-    } else {
-        target.relationship = Some(RelationshipStatus::User);
-    }
-
-    Ok(json!(target.with(perm)))
+    Ok(json!(
+        target
+            .from(&user)
+            .with(perm)
+    ))
 }
-- 
GitLab