flabk/flabk/src/svc/profiles.rs

149 lines
3.4 KiB
Rust

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<User, UserError> {
Ok(self.db.user(username.into()).await?.into())
}
pub async fn stats(&self, username: String) -> Result<UserStats, UserError> {
Ok(self.db.user_stats(username.into()).await?.into())
}
pub async fn profile(&self, username: String) -> Result<Profile, UserError> {
Ok((
self.user(username.clone()).await?,
self.stats(username).await?,
)
.into())
}
pub async fn create_user(
&self,
username: String,
password: String,
email: String,
) -> Result<User, UserError> {
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<String>,
pub host: Option<String>,
pub avatar_uri: Option<String>,
pub bio: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct UserStats {
pub post_count: i64,
pub following: i64,
pub followers: i64,
}
impl From<users::UserStats> 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<users::User> 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<db::DBError> 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(),
}
}
}