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}