Skip to main content

nexus_common/models/user/
relationship.rs

1use crate::models::follow::{Followers, UserFollows};
2use crate::models::user::Muted;
3
4use super::UserCounts;
5use crate::types::DynError;
6use serde::{Deserialize, Serialize};
7use utoipa::ToSchema;
8
9/// Represents the relationship of the user that views and user being viewed.
10#[derive(Serialize, Deserialize, ToSchema, Debug, Default)]
11pub struct Relationship {
12    pub following: bool,
13    pub followed_by: bool,
14    pub muted: bool,
15}
16
17impl Relationship {
18    // Retrieves user-viewer relationship
19    pub async fn get_by_id(
20        user_id: &str,
21        viewer_id: Option<&str>,
22    ) -> Result<Option<Self>, DynError> {
23        match viewer_id {
24            None => Ok(None),
25            Some(v_id) => Self::get_from_index(user_id, v_id).await,
26        }
27    }
28
29    /// Retrieves relationship from Followers/Following Redis index sets.
30    pub async fn get_from_index(
31        user_id: &str,
32        viewer_id: &str,
33    ) -> Result<Option<Relationship>, DynError> {
34        let user_exist = UserCounts::get_from_index(user_id).await?;
35        let viewer_exist = UserCounts::get_from_index(viewer_id).await?;
36
37        // Make sure users exist before get their relationship
38        if user_exist.is_none() || viewer_exist.is_none() {
39            return Ok(None);
40        }
41
42        let (following, followed_by, muted) = tokio::try_join!(
43            Followers::check(user_id, viewer_id),
44            Followers::check(viewer_id, user_id),
45            Muted::check(viewer_id, user_id),
46        )?;
47
48        Ok(Some(Self {
49            followed_by,
50            following,
51            muted,
52        }))
53    }
54}