Skip to main content

nexus_common/models/user/
muted.rs

1use crate::db::{execute_graph_operation, get_neo4j_graph, queries, OperationOutcome, RedisOps};
2use crate::types::DynError;
3use async_trait::async_trait;
4use chrono::Utc;
5use serde::{Deserialize, Serialize};
6use utoipa::ToSchema;
7
8#[derive(Serialize, Deserialize, ToSchema, Default, Debug)]
9pub struct Muted(pub Vec<String>);
10
11impl AsRef<[String]> for Muted {
12    fn as_ref(&self) -> &[String] {
13        &self.0
14    }
15}
16
17#[async_trait]
18impl RedisOps for Muted {}
19
20impl Muted {
21    fn from_vec(vec: Vec<String>) -> Self {
22        Self(vec)
23    }
24
25    pub async fn get_by_id(
26        user_id: &str,
27        skip: Option<usize>,
28        limit: Option<usize>,
29    ) -> Result<Option<Self>, DynError> {
30        match Self::get_from_index(user_id, skip, limit).await? {
31            Some(mutes) => Ok(Some(Self::from_vec(mutes))),
32            None => {
33                let graph_response = Self::get_from_graph(user_id, skip, limit).await?;
34                if let Some(follows) = graph_response {
35                    follows.put_to_index(user_id).await?;
36                    return Ok(Some(follows));
37                }
38                Ok(None)
39            }
40        }
41    }
42
43    async fn get_from_index(
44        user_id: &str,
45        skip: Option<usize>,
46        limit: Option<usize>,
47    ) -> Result<Option<Vec<String>>, DynError> {
48        Self::try_from_index_set(&[user_id], skip, limit, None).await
49    }
50
51    async fn get_from_graph(
52        user_id: &str,
53        skip: Option<usize>,
54        limit: Option<usize>,
55    ) -> Result<Option<Self>, DynError> {
56        let mut result;
57        {
58            let graph = get_neo4j_graph()?;
59            let query = queries::get::get_user_muted(user_id, skip, limit);
60
61            let graph = graph.lock().await;
62            result = graph.execute(query).await?;
63        }
64
65        if let Some(row) = result.next().await? {
66            let user_exists: bool = row.get("user_exists").unwrap_or(false);
67            if !user_exists {
68                return Ok(None);
69            }
70
71            match row.get::<Option<Vec<String>>>("muted_ids") {
72                Ok(response) => {
73                    if let Some(connections) = response {
74                        Ok(Some(Self::from_vec(connections)))
75                    } else {
76                        Ok(Some(Self::default()))
77                    }
78                }
79                Err(_e) => Ok(None),
80            }
81        } else {
82            Ok(None)
83        }
84    }
85
86    pub async fn put_to_index(&self, user_id: &str) -> Result<(), DynError> {
87        let user_list_ref: Vec<&str> = self.as_ref().iter().map(|id| id.as_str()).collect();
88        Self::put_index_set(&[user_id], &user_list_ref, None, None).await
89    }
90
91    pub async fn put_to_graph(user_id: &str, muted_id: &str) -> Result<OperationOutcome, DynError> {
92        let indexed_at = Utc::now().timestamp_millis();
93        let query = queries::put::create_mute(user_id, muted_id, indexed_at);
94        execute_graph_operation(query).await
95    }
96
97    pub async fn reindex(user_id: &str) -> Result<(), DynError> {
98        match Self::get_from_graph(user_id, None, None).await? {
99            Some(muted) => muted.put_to_index(user_id).await?,
100            None => tracing::error!(
101                "{}: Could not found user muted relationship in the graph",
102                user_id
103            ),
104        }
105        Ok(())
106    }
107
108    pub async fn del_from_graph(
109        user_id: &str,
110        muted_id: &str,
111    ) -> Result<OperationOutcome, DynError> {
112        let query = queries::del::delete_mute(user_id, muted_id);
113        execute_graph_operation(query).await
114    }
115
116    pub async fn del_from_index(&self, user_id: &str) -> Result<(), DynError> {
117        self.remove_from_index_set(&[user_id]).await
118    }
119
120    // Checks whether a user is muted
121    pub async fn check(user_id: &str, muted_id: &str) -> Result<bool, DynError> {
122        let user_key_parts = &[user_id][..];
123        let (_, muted) = Self::check_set_member(user_key_parts, muted_id).await?;
124        Ok(muted)
125    }
126}