Constant REPOSITORIES
Source pub const REPOSITORIES: &str = r#"#![allow(unused)]
use chrono::{DateTime, Utc};
use futures::stream::TryStreamExt;
use mongodb::{
bson::{doc, oid::ObjectId},
error::{Error, Result},
options::ClientOptions,
Client, Collection,
};
use serde::{Deserialize, Serialize};
use crate::models::UserDocument;
#[derive(Debug)]
pub struct UserRepository {
collection: Collection<UserDocument>,
}
impl UserRepository {
pub fn new(client: &Client, db_name: &str, collection_name: &str) -> Self {
let collection = client
.database(db_name)
.collection::<UserDocument>(collection_name);
Self { collection }
}
/// CREATE a new user
pub async fn create_user(
&self,
username: &str,
email: &str,
password: &str,
) -> Result<UserDocument> {
if let Some(_) = self.collection.find_one(doc! { "email": email }).await? {
return Err(Error::from(std::io::Error::new(
std::io::ErrorKind::AlreadyExists,
"A user with this email already exists.",
)));
}
let user = UserDocument {
id: ObjectId::new(),
username: username.to_string(),
email: email.to_string(),
password: password.to_string(),
created_at: Utc::now(),
};
self.collection.insert_one(&user).await?;
Ok(user)
}
/// GET user by id
pub async fn get_user_by_id(&self, id: &str) -> Result<Option<UserDocument>> {
match ObjectId::parse_str(id) {
Ok(object_id) => {
let filter = doc! { "_id": object_id };
let user = self.collection.find_one(filter).await?;
Ok(user)
}
Err(_) => Ok(None), // Invalid ID treated as "not found"
}
}
/// GET user by email
pub async fn get_user_by_email(&self, email: &str) -> Result<Option<UserDocument>> {
let filter = doc! { "email": email };
let user = self.collection.find_one(filter).await?;
Ok(user)
}
/// UPDATE a user
pub async fn update_user(
&self,
id: &str,
username: Option<&str>,
email: Option<&str>,
password: Option<&str>,
) -> Result<Option<UserDocument>> {
let object_id = match ObjectId::parse_str(id) {
Ok(oid) => oid,
Err(_) => return Ok(None),
};
let mut update_doc = doc! {};
if let Some(username) = username {
update_doc.insert("username", username);
}
if let Some(email) = email {
update_doc.insert("email", email);
}
if let Some(password) = password {
update_doc.insert("password", password);
}
if update_doc.is_empty() {
return Ok(None);
}
let filter = doc! { "_id": object_id };
let update = doc! { "$set": update_doc };
let user = self.collection.find_one_and_update(filter, update).await?;
Ok(user)
}
/// DELETE a user
pub async fn delete_user(&self, id: &str) -> Result<Option<UserDocument>> {
let object_id = match ObjectId::parse_str(id) {
Ok(oid) => oid,
Err(_) => return Ok(None),
};
let filter = doc! { "_id": object_id };
let user = self.collection.find_one_and_delete(filter).await?;
Ok(user)
}
/// GET all users
pub async fn list_users(&self) -> Result<Vec<UserDocument>> {
let filter = doc! {};
let mut cursor = self.collection.find(filter).await?;
let mut users = Vec::new();
while let Some(user) = cursor.try_next().await? {
users.push(user);
}
Ok(users)
}
}
"#;