use super::collections::users::Users;
use super::settings::user_settings::UserSettings;
use crate::result::{Error, Result, SettingsFileError, UsersError};
use settings_manager::prelude::{ListSetting, SystemSettings};
use thot_core::result::{Error as CoreError, ResourceError};
use thot_core::system::User;
use thot_core::types::ResourceId;
use validator;
pub fn user_by_id(id: &ResourceId) -> Result<User> {
let mut users = load_users()?;
let users: Vec<&User> = users
.items()
.iter()
.filter(|user| &user.rid == id)
.collect();
match users.len() {
0 => Err(Error::CoreError(CoreError::ResourceError(
ResourceError::DoesNotExist(id.id.to_string()),
))),
1 => Ok(users[0].clone()),
_ => Err(Error::UsersError(UsersError::DuplicateEmail(
id.id.to_string(),
))),
}
}
pub fn user_by_email(email: &str) -> Result<User> {
let mut users = load_users()?;
let users: Vec<&User> = users
.items()
.iter()
.filter(|user| user.email == email)
.collect();
match users.len() {
0 => Err(Error::CoreError(CoreError::ResourceError(
ResourceError::DoesNotExist(email.to_string()),
))),
1 => Ok(users[0].clone()),
_ => Err(Error::UsersError(UsersError::DuplicateEmail(
email.to_string(),
))),
}
}
pub fn add_user(user: User) -> Result {
if !validator::validate_email(&user.email) {
return Err(Error::UsersError(UsersError::InvalidEmail(user.email)));
}
let mut users = load_users()?;
let user_count = user_count_by_email(&user.email, &users);
if user_count > 0 {
return Err(Error::UsersError(UsersError::DuplicateEmail(user.email)));
}
users.push(user);
save_users(users)
}
pub fn delete_user(id: &ResourceId) -> Result {
let mut users = load_users()?;
let mut settings = load_user_settings()?;
users.items().retain(|user| user.rid != *id);
if settings.active_user == Some(id.clone()) {
settings.active_user = None;
save_user_settings(settings)?;
}
save_users(users)
}
pub fn delete_user_by_email(email: &str) -> Result {
let user = match user_by_email(email) {
Err(_) => return Ok(()), Ok(u) => u,
};
let id = user.rid;
delete_user(&id)
}
pub fn update_user(user: User) -> Result {
if !validator::validate_email(&user.email) {
return Err(Error::UsersError(UsersError::InvalidEmail(user.email)));
}
let user_id = user.rid.clone();
let mut users = load_users()?;
validate_user_by_id(&user_id, &users)?;
users.items().retain(|u| u.rid != user_id);
users.push(user);
save_users(users)
}
pub fn set_active_user(id: &ResourceId) -> Result {
let users = load_users()?;
validate_user_by_id(id, &users)?;
let mut settings = load_user_settings()?;
settings.active_user = Some(id.clone());
save_user_settings(settings)
}
pub fn set_active_user_by_email(email: &str) -> Result {
let user = user_by_email(email)?;
let mut settings = load_user_settings()?;
settings.active_user = Some(user.rid.into());
save_user_settings(settings)
}
pub fn unset_active_user() -> Result {
let mut settings = load_user_settings()?;
settings.active_user = None;
save_user_settings(settings)
}
fn user_count_by_id(id: &ResourceId, users: &Users) -> u32 {
let mut user_count = 0;
for u in users.users.iter() {
if u.rid == *id {
user_count += 1;
}
}
user_count
}
fn validate_user_by_id(id: &ResourceId, users: &Users) -> Result {
let user_count = user_count_by_id(id, users);
if user_count == 0 {
return Err(Error::CoreError(CoreError::ResourceError(
ResourceError::DoesNotExist(id.id.to_string()),
)));
} else if user_count > 1 {
return Err(Error::CoreError(CoreError::ResourceError(
ResourceError::DuplicateId(id.clone()),
)));
}
Ok(())
}
fn user_count_by_email(email: &str, users: &Users) -> usize {
users
.users
.iter()
.filter(|user| user.email == email)
.collect::<Vec<&User>>()
.len()
}
fn load_user_settings() -> Result<UserSettings> {
match UserSettings::load() {
Ok(sets) => Ok(sets),
Err(err) => {
return Err(Error::SettingsFileError(SettingsFileError::CouldNotLoad(
err,
)))
}
}
}
fn save_user_settings(settings: UserSettings) -> Result {
match settings.save() {
Ok(_) => Ok(()),
Err(err) => Err(Error::SettingsFileError(SettingsFileError::CouldNotSave(
err,
))),
}
}
fn load_users() -> Result<Users> {
match Users::load() {
Ok(users) => Ok(users),
Err(err) => {
return Err(Error::SettingsFileError(SettingsFileError::CouldNotLoad(
err,
)))
}
}
}
fn save_users(users: Users) -> Result {
match users.save() {
Ok(_) => Ok(()),
Err(err) => Err(Error::SettingsFileError(SettingsFileError::CouldNotSave(
err,
))),
}
}
#[cfg(test)]
#[path = "./users_test.rs"]
mod users_test;