mod auth; mod database; mod error; mod memory; use auth::Auth; use database::Database; use error::Error; use memory::Memory; use sqlite::{Connection, Transaction}; use std::{rc::Rc, sync::RwLock}; /// Authorization wrapper for Gemini protocol /// /// https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates pub struct Gemini { pub auth: Rc, pub database: Rc, pub memory: Rc, } impl Gemini { // Constructors /// Create new `Self` pub fn new( connection: Rc>, profile_identity_id: Rc, ) -> Result { // Init components let auth = match Auth::new(connection.clone()) { Ok(auth) => Rc::new(auth), Err(_) => return Err(Error::AuthInit), // @TODO }; let database = Rc::new(Database::new(connection, profile_identity_id)); let memory = Rc::new(Memory::new()); // Init `Self` let this = Self { auth, database, memory, }; // Build initial index Self::index(&this)?; Ok(this) } // Actions /// Create new `Memory` index from `Database` for `Self` pub fn index(&self) -> Result<(), Error> { // Cleanup previous records self.memory.clear(); // Build new index match self.database.records() { Ok(records) => { for record in records { if self.memory.add(record.id, record.pem).is_err() { return Err(Error::MemoryIndex); // @TODO } } } Err(_) => return Err(Error::DatabaseIndex), // @TODO }; Ok(()) // @TODO } // @TODO create new identity API } // Tools pub fn migrate(tx: &Transaction) -> Result<(), String> { // Migrate self components if let Err(e) = database::init(tx) { return Err(e.to_string()); } // Delegate migration to childs auth::migrate(tx)?; // Success Ok(()) }