use std::{fmt, io};
use log::{debug, error, info};
use crate::{config::create_data_dir, param::Params};
pub const DEFAULT_USER_ID: &[u8] = b"default";
const DEFAULT_USER_NAME: &str = "Default";
#[derive(Debug)]
pub struct Boxes {
manager: koibumi_box_sync::Manager,
user: koibumi_box_sync::User,
unread_count: usize,
selected_identity_index: Option<usize>,
selected_contact_index: Option<usize>,
}
impl Boxes {
pub fn manager(&self) -> &koibumi_box_sync::Manager {
&self.manager
}
pub fn manager_mut(&mut self) -> &mut koibumi_box_sync::Manager {
&mut self.manager
}
pub fn user(&self) -> &koibumi_box_sync::User {
&self.user
}
pub fn user_mut(&mut self) -> &mut koibumi_box_sync::User {
&mut self.user
}
pub fn unread_count(&self) -> usize {
self.unread_count
}
pub fn set_unread_count(&mut self, count: usize) {
self.unread_count = count;
}
pub fn increment_unread_count(&mut self) {
if self.unread_count == usize::MAX {
error!("unread_count overflow");
return;
}
self.unread_count += 1;
}
pub fn decrement_unread_count(&mut self) {
if self.unread_count < 1 {
error!("unread_count underflow");
return;
}
self.unread_count -= 1;
}
pub fn selected_identity_index(&self) -> Option<usize> {
self.selected_identity_index
}
pub fn set_selected_identity_index(&mut self, value: Option<usize>) {
self.selected_identity_index = value
}
pub fn selected_contact_index(&self) -> Option<usize> {
self.selected_contact_index
}
pub fn set_selected_contact_index(&mut self, value: Option<usize>) {
self.selected_contact_index = value
}
}
#[derive(Debug)]
pub enum Error {
IoError(io::Error),
RusqliteError(rusqlite::Error),
BoxError(koibumi_box_sync::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::IoError(err) => err.fmt(f),
Self::RusqliteError(err) => err.fmt(f),
Self::BoxError(err) => err.fmt(f),
}
}
}
impl std::error::Error for Error {}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Self::IoError(err)
}
}
impl From<rusqlite::Error> for Error {
fn from(err: rusqlite::Error) -> Self {
Self::RusqliteError(err)
}
}
impl From<koibumi_box_sync::Error> for Error {
fn from(err: koibumi_box_sync::Error) -> Self {
Self::BoxError(err)
}
}
pub fn prepare(params: &Params) -> Result<Boxes, Error> {
let mut path = create_data_dir(params)?;
path.push("box.db");
let conn = rusqlite::Connection::open(path)?;
let manager = koibumi_box_sync::Manager::new(conn)?;
match manager.add_user(DEFAULT_USER_ID, DEFAULT_USER_NAME) {
Ok(_) => {
info!("Default user added");
}
Err(koibumi_box_sync::Error::AlreadyExists) => {
debug!("Default user already exists");
}
Err(err) => return Err(err.into()),
}
let user = manager.user(DEFAULT_USER_ID)?;
Ok(Boxes {
manager,
user,
unread_count: 0,
selected_identity_index: None,
selected_contact_index: None,
})
}