stat_summoner/module/suggestions/utils.rs
1use crate::models::data::User;
2use chrono::Utc;
3use mongodb::bson::doc;
4use mongodb::Collection;
5
6/// ⚙️ Checks if a user is blacklisted.
7///
8/// This asynchronous function queries a MongoDB collection to check whether a user with the specified `user_id` exists in the blacklist.
9/// It returns `true` if the user is found, and `false` otherwise.
10///
11/// # Parameters:
12/// - `collection`: A reference to a MongoDB collection of `BlackList` documents.
13/// - `user_id`: A string slice representing the ID of the user to check.
14///
15/// # Returns:
16/// - `Result<bool, mongodb::error::Error>`: On success, returns `true` if the user is blacklisted, `false` otherwise.
17/// On failure, returns an `Error` from MongoDB detailing the issue.
18///
19/// # Example:
20/// ```rust
21/// let is_blacklisted = is_user_blacklisted(&collection, "123456789012345678").await?;
22/// if is_blacklisted {
23/// println!("User is blacklisted.");
24/// } else {
25/// println!("User is not blacklisted.");
26/// }
27/// ```
28///
29/// # ⚠️ Notes:
30/// - The function uses MongoDB's `find_one` method to search for a document with a matching `user_id`.
31/// - If no matching document is found, the function returns `false`.
32///
33/// # Related Structures:
34/// - `User`: Represents the structure of a User in the database.
35///
36/// # Dependencies:
37/// - Requires a MongoDB collection containing `BlackList` documents.
38pub async fn is_user_blacklisted(
39 collection: &Collection<User>,
40 user_id: &str,
41) -> mongodb::error::Result<bool> {
42 if let Some(user) = collection.find_one(doc! { "user_id": user_id }).await? {
43 Ok(user.is_blacklisted)
44 } else {
45 Ok(false)
46 }
47}
48
49/// ⚙️ Checks if a user can make a new suggestion based on the time of their last suggestion.
50///
51/// This asynchronous function queries a MongoDB collection to check the `last_suggestion_at` timestamp of a user.
52/// It returns `true` if the user can make a new suggestion (i.e., more than an hour has passed since their last suggestion),
53/// and `false` otherwise.
54///
55/// # Parameters:
56/// - `collection`: A reference to a MongoDB collection of `User` documents.
57/// - `user_id`: A string slice representing the ID of the user to check.
58///
59/// # Returns:
60/// - `Result<bool, mongodb::error::Error>`: On success, returns `true` if the user can make a new suggestion, `false` otherwise.
61/// On failure, returns an `Error` from MongoDB detailing the issue.
62///
63/// # Example:
64/// ```rust
65/// let can_suggest = can_user_make_suggestion(&collection, "123456789012345678").await?;
66/// if can_suggest {
67/// println!("User can make a new suggestion.");
68/// } else {
69/// println!("User cannot make a new suggestion yet.");
70/// }
71/// ```
72///
73/// # ⚠️ Notes:
74/// - The function uses MongoDB's `find_one` method to search for a document with a matching `user_id`.
75/// - If no matching document is found, the function returns `false`.
76/// - The function checks if the `last_suggestion_at` timestamp is more than an hour ago.
77///
78/// # Related Structures:
79/// - `User`: Represents the structure of a user in the database.
80///
81/// # Dependencies:
82/// - Requires a MongoDB collection containing `User` documents.
83/// - Uses the `chrono` crate to handle time calculations.
84pub async fn can_user_make_suggestion(
85 collection: &Collection<User>,
86 user_id: &str,
87) -> mongodb::error::Result<bool> {
88 if let Some(user) = collection.find_one(doc! { "user_id": user_id }).await? {
89 let user_suggestion_timestamp = user.last_suggestion_at;
90 let now = Utc::now().timestamp() as u64;
91 println!(
92 "user_suggestion: {}, now: {}, now - user_suggestion: {}",
93 user_suggestion_timestamp,
94 now,
95 now - user_suggestion_timestamp
96 );
97 if now - user_suggestion_timestamp > 3600 {
98 Ok(true)
99 } else {
100 Ok(false)
101 }
102 } else {
103 Ok(true)
104 }
105}
106
107/// ⚙️ Adds a user to the blacklist.
108///
109/// This asynchronous function inserts a new document into a MongoDB collection to blacklist a user.
110/// The document includes the `user_id`, `username`, and a timestamp indicating when the user was added to the blacklist.
111///
112/// # Parameters:
113/// - `collection`: A reference to a MongoDB collection of `BlackList` documents.
114/// - `user_id`: A string slice representing the ID of the user to blacklist.
115/// - `username`: A string slice representing the username of the user to blacklist.
116///
117/// # Returns:
118/// - `Result<(), mongodb::error::Error>`: Returns `Ok(())` if the user is successfully blacklisted.
119/// On failure, returns an `Error` from MongoDB detailing the issue.
120///
121/// # Example:
122/// ```rust
123/// add_user_to_blacklist(&collection, "123456789012345678", "JohnDoe").await?;
124/// println!("User has been blacklisted.");
125/// ```
126///
127/// # ⚠️ Notes:
128/// - The function creates a new `BlackList` entry with the provided `user_id` and `username`.
129/// - The `created_at` field is set to the current timestamp in seconds since the UNIX epoch.
130///
131/// # Related Structures:
132/// - `BlackList`: Represents the structure of a blacklisted user in the database.
133///
134/// # Dependencies:
135/// - Requires a MongoDB collection containing `BlackList` documents.
136/// - Uses the `chrono` crate to generate a timestamp for the `created_at` field.
137pub async fn add_user_to_blacklist(
138 collection: &Collection<User>,
139 user_id: &str,
140) -> mongodb::error::Result<()> {
141 if let Some(mut user) = collection.find_one(doc! { "user_id": user_id }).await? {
142 user.is_blacklisted = true;
143 collection
144 .replace_one(doc! { "user_id": user_id }, user)
145 .await?;
146 }
147 Ok(())
148}