use serde::Serialize; use crate::{ database::{ db, users::{self, UserSelect, Users}, }, sec, }; #[derive(Clone)] pub struct Profiler { db: Users, } impl Profiler { pub fn new(db: Users) -> Self { Self { db } } pub async fn user(&self, username: String) -> Result { Ok(self.db.user(username.into()).await?.into()) } pub async fn stats(&self, username: String) -> Result { Ok(self.db.user_stats(username.into()).await?.into()) } pub async fn profile(&self, username: String) -> Result { Ok(( self.user(username.clone()).await?, self.stats(username).await?, ) .into()) } pub async fn create_user( &self, username: String, password: String, email: String, ) -> Result { let result = self .db .create_user(users::User { id: String::new(), username, host: None, display_name: None, password_hash: sec::hash(password), email, avatar_uri: None, bio: None, }) .await?; Ok(User::from(result)) } } #[derive(Clone, Debug, Serialize)] pub struct User { pub id: String, pub username: String, pub display_name: Option, pub host: Option, pub avatar_uri: Option, pub bio: Option, } #[derive(Debug, Clone, Serialize)] pub struct UserStats { pub post_count: i64, pub following: i64, pub followers: i64, } impl From for UserStats { fn from(u: users::UserStats) -> Self { Self { post_count: u.post_count, following: u.following, followers: u.followers, } } } #[derive(Debug, Clone, Serialize)] pub struct Profile { pub user: User, pub stats: UserStats, } impl From<(User, UserStats)> for Profile { fn from((user, stats): (User, UserStats)) -> Self { Self { user: user.into(), stats: stats.into(), } } } impl From for User { fn from(u: users::User) -> Self { Self { id: u.id, display_name: u.display_name.or(Some(format!( "@{}{}", u.username, u.host .clone() .map(|h| format!("@{}", h)) .unwrap_or(String::new()), ))), username: u.username, host: u.host, avatar_uri: u.avatar_uri, bio: u.bio, } } } #[derive(Debug, Clone)] pub enum UserError { Duplicate, NotFound, Other(String), } impl From for UserError { fn from(err: db::DBError) -> Self { match err { db::DBError::Duplicate => Self::Duplicate, db::DBError::NotFound => Self::NotFound, db::DBError::Other(e) => Self::Other(e.to_string()), } } } impl ToString for UserError { fn to_string(&self) -> String { match self { Self::Duplicate => String::from("duplicate insert"), Self::NotFound => String::from("not found"), Self::Other(err) => err.clone(), } } }