mod auth;
mod certificate;
mod database;
mod error;
mod memory;
use auth::Auth;
use database::Database;
pub use error::Error;
use memory::Memory;
use gtk::glib::DateTime;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
pub struct Gemini {
pub auth: Rc<Auth>,
pub database: Rc<Database>,
pub memory: Rc<Memory>,
}
impl Gemini {
pub fn new(
connection: Rc<RwLock<Connection>>,
profile_identity_id: Rc<i64>,
) -> Result<Self, Error> {
let auth = match Auth::new(connection.clone()) {
Ok(auth) => Rc::new(auth),
Err(reason) => return Err(Error::Auth(reason)),
};
let database = Rc::new(Database::new(connection, profile_identity_id.clone()));
let memory = Rc::new(Memory::new());
let this = Self {
auth,
database,
memory,
};
Self::index(&this)?;
Ok(this)
}
pub fn add(&self, pem: &str) -> Result<i64, Error> {
match self.database.add(pem) {
Ok(profile_identity_gemini_id) => {
self.index()?;
Ok(profile_identity_gemini_id)
}
Err(reason) => Err(Error::Database(reason)),
}
}
pub fn make(&self, time: Option<(DateTime, DateTime)>, name: &str) -> Result<i64, Error> {
match certificate::generate(
match time {
Some(value) => value,
None => (
DateTime::now_local().unwrap(),
DateTime::from_local(9999, 12, 31, 23, 59, 59.9).unwrap(), ),
},
name,
) {
Ok(pem) => self.add(&pem),
Err(reason) => Err(Error::Certificate(reason)),
}
}
pub fn index(&self) -> Result<(), Error> {
if let Err(reason) = self.memory.clear() {
return Err(Error::Memory(reason));
}
match self.database.records() {
Ok(records) => {
for record in records {
if let Err(reason) = self.memory.add(record.id, record.pem) {
return Err(Error::Memory(reason));
}
}
}
Err(reason) => return Err(Error::Database(reason)),
};
Ok(())
}
}
pub fn migrate(tx: &Transaction) -> Result<(), String> {
if let Err(e) = database::init(tx) {
return Err(e.to_string());
}
auth::migrate(tx)?;
Ok(())
}