use serde::{Serialize, Deserialize}; use bson::{oid::ObjectId, DateTime, doc}; use mongodb::{Collection, error::Error}; use crate::app_error::AppError; #[derive(Debug, Serialize, Deserialize)] pub struct User { #[serde(rename = "_id", skip_serializing_if = "Option::is_none")] pub _id: Option, pub email: String, pub password_hash: String, pub password_salt: String, pub created_at: bson::DateTime } #[derive(Debug, Deserialize)] pub struct NewUserInput { pub email: String, pub password_hash: String, pub password_salt: String } impl User { pub async fn insert(collection: &Collection, input: NewUserInput) -> Result<(), Error> { let user = User { _id: None, email: input.email, password_hash: input.password_hash, password_salt: input.password_salt, created_at: DateTime::now() }; collection.insert_one(user, None).await?; Ok(()) } pub async fn find_by_email(collection: &Collection, email: &str) -> Result { match collection.find_one(doc!{"email": email}, None).await { Ok(Some(u)) => Ok(u), Ok(None) => Err(AppError::invalid_input("No user with this email address")), Err(e) => Err(AppError::Database(e.into())) } } pub async fn find_by_id(collection: &Collection, user_id: String) -> Result { let object_id = ObjectId::parse_str(id_str)?; match collection.find_one(doc!{"_id", object_id}) { Ok(Some(u)) => Ok(u), Ok(None) => Err(AppError::auth), Err(e) => Err(AppError::Database(e.into())) } } }