revolt_database/models/server_members/ops/
reference.rs

1use revolt_result::Result;
2
3use crate::ReferenceDb;
4use crate::{FieldsMember, Member, MemberCompositeKey, PartialMember};
5
6use super::{AbstractServerMembers, ChunkedServerMembersGenerator};
7
8#[async_trait]
9impl AbstractServerMembers for ReferenceDb {
10    /// Insert a new server member into the database
11    async fn insert_or_merge_member(&self, member: &Member) -> Result<Option<Member>> {
12        let mut server_members = self.server_members.lock().await;
13        if server_members.contains_key(&member.id) {
14            Err(create_database_error!("insert", "member"))
15        } else {
16            server_members.insert(member.id.clone(), member.clone());
17            Ok(None)
18        }
19    }
20
21    /// Fetch a server member by their id
22    async fn fetch_member(&self, server_id: &str, user_id: &str) -> Result<Member> {
23        let server_members = self.server_members.lock().await;
24        server_members
25            .get(&MemberCompositeKey {
26                server: server_id.to_string(),
27                user: user_id.to_string(),
28            })
29            .cloned()
30            .ok_or_else(|| create_error!(NotFound))
31    }
32
33    /// Fetch all members in a server
34    async fn fetch_all_members(&self, server_id: &str) -> Result<Vec<Member>> {
35        let server_members = self.server_members.lock().await;
36        Ok(server_members
37            .values()
38            .filter(|member| member.id.server == server_id)
39            .cloned()
40            .collect())
41    }
42
43    /// Fetch all members in a server as an iterator
44    async fn fetch_all_members_chunked(
45        &self,
46        server_id: &str,
47    ) -> Result<ChunkedServerMembersGenerator> {
48        let server_members = self.server_members.lock().await;
49
50        let members = server_members
51            .clone()
52            .into_values()
53            .filter(move |member| member.id.server == server_id)
54            .collect();
55
56        // this is inefficient as shit but its the reference db so its fine
57        Ok(ChunkedServerMembersGenerator::new_reference(members))
58    }
59
60    /// Fetch all members that have any of the roles given
61    async fn fetch_all_members_with_roles(
62        &self,
63        server_id: &str,
64        roles: &[String],
65    ) -> Result<Vec<Member>> {
66        let server_members = self.server_members.lock().await;
67
68        Ok(server_members
69            .clone()
70            .into_values()
71            .filter(|member| {
72                member.id.server == server_id
73                    && !member
74                        .roles
75                        .iter()
76                        .filter(|p| roles.contains(*p))
77                        .collect::<Vec<&String>>()
78                        .is_empty()
79            })
80            .collect())
81    }
82
83    async fn fetch_all_members_with_roles_chunked(
84        &self,
85        server_id: &str,
86        roles: &[String],
87    ) -> Result<ChunkedServerMembersGenerator> {
88        let server_members = self.server_members.lock().await;
89
90        let resp = server_members
91            .clone()
92            .into_values()
93            .filter(|member| {
94                member.id.server == server_id
95                    && !member
96                        .roles
97                        .iter()
98                        .filter(|p| roles.contains(*p))
99                        .collect::<Vec<&String>>()
100                        .is_empty()
101            })
102            .collect();
103
104        return Ok(ChunkedServerMembersGenerator::new_reference(resp));
105    }
106
107    /// Fetch all memberships for a user
108    async fn fetch_all_memberships(&self, user_id: &str) -> Result<Vec<Member>> {
109        let server_members = self.server_members.lock().await;
110        Ok(server_members
111            .values()
112            .filter(|member| member.id.user == user_id)
113            .cloned()
114            .collect())
115    }
116
117    /// Fetch multiple members by their ids
118    async fn fetch_members(&self, server_id: &str, ids: &[String]) -> Result<Vec<Member>> {
119        let server_members = self.server_members.lock().await;
120        Ok(ids
121            .iter()
122            .filter_map(|id| {
123                server_members
124                    .get(&MemberCompositeKey {
125                        server: server_id.to_string(),
126                        user: id.to_string(),
127                    })
128                    .cloned()
129            })
130            .collect())
131    }
132
133    /// Fetch member count of a server
134    async fn fetch_member_count(&self, server_id: &str) -> Result<usize> {
135        let server_members = self.server_members.lock().await;
136        Ok(server_members
137            .values()
138            .filter(|member| member.id.server == server_id)
139            .count())
140    }
141
142    /// Fetch server count of a user
143    async fn fetch_server_count(&self, user_id: &str) -> Result<usize> {
144        let server_members = self.server_members.lock().await;
145        Ok(server_members
146            .values()
147            .filter(|member| member.id.user == user_id)
148            .count())
149    }
150
151    /// Update information for a server member
152    async fn update_member(
153        &self,
154        id: &MemberCompositeKey,
155        partial: &PartialMember,
156        remove: Vec<FieldsMember>,
157    ) -> Result<()> {
158        let mut server_members = self.server_members.lock().await;
159        if let Some(member) = server_members.get_mut(id) {
160            for field in remove {
161                #[allow(clippy::disallowed_methods)]
162                member.remove_field(&field);
163            }
164
165            member.apply_options(partial.clone());
166            Ok(())
167        } else {
168            Err(create_error!(NotFound))
169        }
170    }
171
172    /// Soft delete a member
173    async fn soft_delete_member(&self, id: &MemberCompositeKey) -> Result<()> {
174        let mut server_members = self.server_members.lock().await;
175
176        let member = server_members.get_mut(id);
177        if let Some(member) = member {
178            if member.in_timeout() {
179                panic!("Soft deletion is not implemented.")
180            } else if server_members.remove(id).is_some() {
181                Ok(())
182            } else {
183                Err(create_error!(NotFound))
184            }
185        } else {
186            Err(create_error!(NotFound))
187        }
188    }
189
190    /// Delete a server member by their id
191    async fn force_delete_member(&self, id: &MemberCompositeKey) -> Result<()> {
192        let mut server_members = self.server_members.lock().await;
193        if server_members.remove(id).is_some() {
194            Ok(())
195        } else {
196            Err(create_error!(NotFound))
197        }
198    }
199
200    async fn remove_dangling_members(&self) -> Result<()> {
201        todo!()
202    }
203}