From 611addda42420ae20bf63d44113e9bbdbe927ed2 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 16 Nov 2024 20:27:33 +0200 Subject: [PATCH] handle construction results, separate index methods --- src/profile.rs | 2 +- src/profile/identity.rs | 19 ++++++-- src/profile/identity/error.rs | 5 ++ src/profile/identity/gemini.rs | 53 ++++++++++++++++------ src/profile/identity/gemini/auth.rs | 45 +++++++++++------- src/profile/identity/gemini/auth/error.rs | 5 ++ src/profile/identity/gemini/auth/memory.rs | 5 +- src/profile/identity/gemini/error.rs | 6 +++ src/profile/identity/gemini/memory.rs | 5 ++ 9 files changed, 105 insertions(+), 40 deletions(-) create mode 100644 src/profile/identity/error.rs create mode 100644 src/profile/identity/gemini/auth/error.rs create mode 100644 src/profile/identity/gemini/error.rs diff --git a/src/profile.rs b/src/profile.rs index 34eb41dc..f99b1e25 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -96,7 +96,7 @@ impl Profile { // Result Self { bookmark: Rc::new(Bookmark::new(connection.clone(), profile_id.clone())), - identity: Rc::new(Identity::new(connection, profile_id)), + identity: Rc::new(Identity::new(connection, profile_id).unwrap()), // @TODO handle database, config_path, } diff --git a/src/profile/identity.rs b/src/profile/identity.rs index c3073ecf..9b11e6f4 100644 --- a/src/profile/identity.rs +++ b/src/profile/identity.rs @@ -1,7 +1,9 @@ mod database; +mod error; mod gemini; use database::Database; +use error::Error; use gemini::Gemini; use gtk::glib::DateTime; @@ -18,7 +20,7 @@ impl Identity { // Constructors /// Create new `Self` - pub fn new(connection: Rc>, profile_id: Rc) -> Self { + pub fn new(connection: Rc>, profile_id: Rc) -> Result { // Init identity database let database = Rc::new(Database::new(connection.clone())); @@ -27,14 +29,21 @@ impl Identity { Some(identity) => identity.id, None => match database.add(profile_id, true, DateTime::now_local().unwrap(), None) { Ok(id) => id, - Err(_) => todo!(), + Err(_) => return Err(Error::Database), }, }); - Self { + // Init gemini component + let gemini = Rc::new(match Gemini::new(connection, profile_identity_id) { + Ok(result) => result, + Err(_) => return Err(Error::Gemini), + }); + + // Done + Ok(Self { // database, - gemini: Rc::new(Gemini::new(connection, profile_identity_id)), - } + gemini, + }) } /// Get `pem` record match `request` diff --git a/src/profile/identity/error.rs b/src/profile/identity/error.rs new file mode 100644 index 00000000..fdf54de4 --- /dev/null +++ b/src/profile/identity/error.rs @@ -0,0 +1,5 @@ +#[derive(Debug)] +pub enum Error { + Database, + Gemini, +} diff --git a/src/profile/identity/gemini.rs b/src/profile/identity/gemini.rs index 8cb6c96f..d4e8297c 100644 --- a/src/profile/identity/gemini.rs +++ b/src/profile/identity/gemini.rs @@ -1,9 +1,11 @@ mod auth; mod database; +mod error; mod memory; use auth::Auth; use database::Database; +use error::Error; use memory::Memory; use sqlite::{Connection, Transaction}; @@ -14,7 +16,7 @@ use std::{rc::Rc, sync::RwLock}; /// https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates pub struct Gemini { pub auth: Rc, - // pub database: Rc, + pub database: Rc, pub memory: Rc, } @@ -22,29 +24,50 @@ impl Gemini { // Constructors /// Create new `Self` - pub fn new(connection: Rc>, profile_identity_id: Rc) -> Self { - // Init children components - let auth = Rc::new(Auth::new(connection.clone())); + 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 - match database.records() { + 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 memory.add(record.id, record.pem).is_err() { - todo!() + if self.memory.add(record.id, record.pem).is_err() { + return Err(Error::MemoryIndex); // @TODO } } } - Err(reason) => todo!("{reason}"), - } - - Self { - auth, - // database, - memory, - } + Err(_) => return Err(Error::DatabaseIndex), // @TODO + }; + Ok(()) // @TODO } // @TODO create new identity API diff --git a/src/profile/identity/gemini/auth.rs b/src/profile/identity/gemini/auth.rs index 403b10fe..e237fd07 100644 --- a/src/profile/identity/gemini/auth.rs +++ b/src/profile/identity/gemini/auth.rs @@ -1,7 +1,9 @@ mod database; +mod error; mod memory; use database::Database; +use error::Error; use memory::Memory; use sqlite::{Connection, Transaction}; @@ -9,7 +11,7 @@ use std::{rc::Rc, sync::RwLock}; /// API for `profile_identity_gemini_id` + `url` auth pairs operations pub struct Auth { - // pub database: Rc, + pub database: Rc, pub memory: Rc, } @@ -17,33 +19,45 @@ impl Auth { // Constructors /// Create new `Self` - pub fn new(connection: Rc>) -> Self { - // Init children components - let database = Rc::new(Database::new(connection)); - let memory = Rc::new(Memory::new()); + pub fn new(connection: Rc>) -> Result { + // Init `Self` + let this = Self { + database: Rc::new(Database::new(connection)), + memory: Rc::new(Memory::new()), + }; // Build initial index - match database.records(None) { + Self::index(&this)?; + + // Done + Ok(this) + } + + // Actions + + /// Create new `Memory` index from `Database` for `Self` + pub fn index(&self) -> Result<(), Error> { + // Clear previous records + self.memory.clear(); + + // Build new index + match self.database.records(None) { Ok(records) => { for record in records { if record.is_active { - if memory + if self + .memory .add(record.url, record.profile_identity_gemini_id) .is_err() { - todo!() + return Err(Error::MemoryIndex); } } } } - Err(reason) => todo!("{reason}"), - } - - // Return new `Self` - Self { - // database, - memory, + Err(_) => return Err(Error::DatabaseIndex), } + Ok(()) } } @@ -58,6 +72,5 @@ pub fn migrate(tx: &Transaction) -> Result<(), String> { // Delegate migration to childs // nothing yet.. - // Success Ok(()) } diff --git a/src/profile/identity/gemini/auth/error.rs b/src/profile/identity/gemini/auth/error.rs new file mode 100644 index 00000000..971fe84a --- /dev/null +++ b/src/profile/identity/gemini/auth/error.rs @@ -0,0 +1,5 @@ +#[derive(Debug)] +pub enum Error { + DatabaseIndex, + MemoryIndex, +} diff --git a/src/profile/identity/gemini/auth/memory.rs b/src/profile/identity/gemini/auth/memory.rs index 0c635e75..e01611b1 100644 --- a/src/profile/identity/gemini/auth/memory.rs +++ b/src/profile/identity/gemini/auth/memory.rs @@ -33,11 +33,10 @@ impl Memory { } } - /* @TODO update feature /// Cleanup index - pub fn clear(&self, url: &str) { + pub fn clear(&self) { self.index.borrow_mut().clear() - } */ + } /// Get `profile_identity_gemini_id` vector match given `request` /// * [Client certificates specification](https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates) diff --git a/src/profile/identity/gemini/error.rs b/src/profile/identity/gemini/error.rs new file mode 100644 index 00000000..53086a7f --- /dev/null +++ b/src/profile/identity/gemini/error.rs @@ -0,0 +1,6 @@ +#[derive(Debug)] +pub enum Error { + AuthInit, + MemoryIndex, + DatabaseIndex, +} diff --git a/src/profile/identity/gemini/memory.rs b/src/profile/identity/gemini/memory.rs index 1f6ee41f..52cd78e9 100644 --- a/src/profile/identity/gemini/memory.rs +++ b/src/profile/identity/gemini/memory.rs @@ -36,4 +36,9 @@ impl Memory { None => Err(Error::NotFound), } } + + /// Cleanup index + pub fn clear(&self) { + self.index.borrow_mut().clear() + } }