Browse Source

collect profile features into one shared struct

master
yggverse 4 weeks ago
parent
commit
25b63c0e02
  1. 35
      src/app.rs
  2. 10
      src/app/browser.rs
  3. 46
      src/main.rs
  4. 53
      src/profile.rs
  5. 25
      src/profile/database.rs

35
src/app.rs

@ -4,7 +4,7 @@ mod database;
use browser::Browser; use browser::Browser;
use database::Database; use database::Database;
use crate::action::Browser as BrowserAction; use crate::{action::Browser as BrowserAction, Profile};
use adw::Application; use adw::Application;
use gtk::{ use gtk::{
gio::SimpleAction, gio::SimpleAction,
@ -13,20 +13,19 @@ use gtk::{
ActionExt, ApplicationExt, ApplicationExtManual, GtkApplicationExt, GtkWindowExt, ToVariant, ActionExt, ApplicationExt, ApplicationExtManual, GtkApplicationExt, GtkWindowExt, ToVariant,
}, },
}; };
use sqlite::{Connection, Transaction}; use sqlite::Transaction;
use std::rc::Rc;
use std::{path::PathBuf, rc::Rc, sync::RwLock};
const APPLICATION_ID: &str = "io.github.yggverse.Yoda"; const APPLICATION_ID: &str = "io.github.yggverse.Yoda";
pub struct App { pub struct App {
profile_database_connection: Rc<RwLock<Connection>>, profile: Rc<Profile>,
gobject: Application, gobject: Application,
} }
impl App { impl App {
// Construct // Construct
pub fn new(profile_database_connection: Rc<RwLock<Connection>>, profile_path: PathBuf) -> Self { pub fn new(profile: Rc<Profile>) -> Self {
// Init actions // Init actions
let browser_action = Rc::new(BrowserAction::new()); let browser_action = Rc::new(BrowserAction::new());
@ -97,7 +96,7 @@ impl App {
// Init components // Init components
let browser = Rc::new(Browser::new( let browser = Rc::new(Browser::new(
profile_path, profile.clone(),
browser_action.clone(), browser_action.clone(),
action_page_new.clone(), action_page_new.clone(),
action_page_close.clone(), action_page_close.clone(),
@ -120,10 +119,10 @@ impl App {
gobject.connect_startup({ gobject.connect_startup({
let browser = browser.clone(); let browser = browser.clone();
let profile_database_connection = profile_database_connection.clone(); let profile = profile.clone();
move |this| { move |this| {
// Init readable connection // Init readable connection
match profile_database_connection.read() { match profile.database().connection().read() {
Ok(connection) => { Ok(connection) => {
// Create transaction // Create transaction
match connection.unchecked_transaction() { match connection.unchecked_transaction() {
@ -161,12 +160,11 @@ impl App {
}); });
gobject.connect_shutdown({ gobject.connect_shutdown({
// let browser = browser.clone();
let profile_database_connection = profile_database_connection.clone();
let browser = browser.clone(); let browser = browser.clone();
let profile = profile.clone();
move |_| { move |_| {
// Init writable connection // Init writable connection
match profile_database_connection.write() { match profile.database().connection().write() {
Ok(mut connection) => { Ok(mut connection) => {
// Create transaction // Create transaction
match connection.transaction() { match connection.transaction() {
@ -219,16 +217,7 @@ impl App {
}); });
// Return activated App struct // Return activated App struct
Self { Self { profile, gobject }
// database,
profile_database_connection,
// Actions (SimpleAction)
// action_update: action_update.simple(),
// Components
// browser,
// GTK
gobject,
}
} }
// Actions // Actions
@ -236,7 +225,7 @@ impl App {
// Begin database migration @TODO // Begin database migration @TODO
{ {
// Init writable connection // Init writable connection
let mut connection = match self.profile_database_connection.try_write() { let mut connection = match self.profile.database().connection().try_write() {
Ok(connection) => connection, Ok(connection) => connection,
Err(e) => todo!("{e}"), Err(e) => todo!("{e}"),
}; };

10
src/app/browser.rs

@ -8,7 +8,7 @@ use database::Database;
use widget::Widget; use widget::Widget;
use window::Window; use window::Window;
use crate::action::Browser as BrowserAction; use crate::{action::Browser as BrowserAction, Profile};
use adw::ApplicationWindow; use adw::ApplicationWindow;
use gtk::{ use gtk::{
gio::{Cancellable, File, SimpleAction}, gio::{Cancellable, File, SimpleAction},
@ -17,7 +17,7 @@ use gtk::{
FileLauncher, FileLauncher,
}; };
use sqlite::Transaction; use sqlite::Transaction;
use std::{path::PathBuf, rc::Rc}; use std::rc::Rc;
pub struct Browser { pub struct Browser {
window: Rc<Window>, window: Rc<Window>,
@ -27,9 +27,7 @@ pub struct Browser {
impl Browser { impl Browser {
// Construct // Construct
pub fn new( pub fn new(
// Extras profile: Rc<Profile>,
profile_path: PathBuf,
// Actions
browser_action: Rc<BrowserAction>, browser_action: Rc<BrowserAction>,
action_page_new: SimpleAction, action_page_new: SimpleAction,
action_page_close: SimpleAction, action_page_close: SimpleAction,
@ -92,7 +90,7 @@ impl Browser {
browser_action.profile().connect_activate({ browser_action.profile().connect_activate({
move |_, _| { move |_, _| {
FileLauncher::new(Some(&File::for_path(&profile_path))).launch( FileLauncher::new(Some(&File::for_path(profile.config_path()))).launch(
None::<&gtk::Window>, None::<&gtk::Window>,
None::<&Cancellable>, None::<&Cancellable>,
|result| { |result| {

46
src/main.rs

@ -1,46 +1,30 @@
mod action; mod action;
mod app; mod app;
mod profile;
use crate::profile::Profile;
use app::App; use app::App;
use gtk::glib::{user_config_dir, ExitCode}; use gtk::glib::ExitCode;
use sqlite::Connection; use std::rc::Rc;
use std::{fs::create_dir_all, rc::Rc, sync::RwLock};
const VENDOR: &str = "YGGverse"; const VENDOR: &str = "YGGverse";
const APP_ID: &str = "Yoda"; // env!("CARGO_PKG_NAME"); const APP_ID: &str = "Yoda";
const BRANCH: &str = "master"; const BRANCH: &str = "master";
fn main() -> ExitCode { fn main() -> ExitCode {
// Init profile path match gtk::init() {
let mut profile_path = user_config_dir(); Ok(_) => App::new(Rc::new(Profile::new(
VENDOR,
profile_path.push(VENDOR); APP_ID,
profile_path.push(APP_ID); BRANCH,
profile_path.push(BRANCH); format!(
profile_path.push(format!(
"{}.{}", "{}.{}",
env!("CARGO_PKG_VERSION_MAJOR"), env!("CARGO_PKG_VERSION_MAJOR"),
env!("CARGO_PKG_VERSION_MINOR") env!("CARGO_PKG_VERSION_MINOR")
)); // @TODO remove after auto-migrate feature implementation )
.as_str(),
if let Err(e) = create_dir_all(&profile_path) { )))
panic!("Failed to create profile directory: {e}") .run(),
}
// Init profile database path
let mut profile_database_path = profile_path.clone();
profile_database_path.push("profile.sqlite3");
// Init database connection
let profile_database_connection = match Connection::open(profile_database_path) {
Ok(connection) => Rc::new(RwLock::new(connection)),
Err(e) => panic!("Failed to connect profile database: {e}"),
};
// Init GTK, start application
match gtk::init() {
Ok(_) => App::new(profile_database_connection, profile_path).run(), // @TODO common struct for profile data
Err(_) => ExitCode::FAILURE, Err(_) => ExitCode::FAILURE,
} }
} }

53
src/profile.rs

@ -0,0 +1,53 @@
mod database;
pub use database::Database;
use gtk::glib::user_config_dir;
use std::{
fs::create_dir_all,
path::{Path, PathBuf},
};
const DB_NAME: &str = "profile.sqlite3";
pub struct Profile {
database: Database,
config_path: PathBuf,
}
impl Profile {
// Constructors
pub fn new(vendor: &str, app_id: &str, branch: &str, version: &str) -> Self {
// Init profile path
let mut config_path = user_config_dir();
config_path.push(vendor);
config_path.push(app_id);
config_path.push(branch);
config_path.push(version); // @TODO remove after auto-migrate feature implementation
if let Err(e) = create_dir_all(&config_path) {
panic!("Failed to create profile directory: {e}")
}
// Init database path
let mut database_path = config_path.clone();
database_path.push(DB_NAME);
// Result
Self {
database: Database::new(database_path.as_path()),
config_path,
}
}
// Getters
pub fn database(&self) -> &Database {
&self.database
}
pub fn config_path(&self) -> &Path {
self.config_path.as_path()
}
}

25
src/profile/database.rs

@ -0,0 +1,25 @@
use sqlite::Connection;
use std::{path::Path, rc::Rc, sync::RwLock};
pub struct Database {
connection: Rc<RwLock<Connection>>,
}
impl Database {
// Constructors
pub fn new(path: &Path) -> Self {
Self {
connection: match Connection::open(path) {
Ok(connection) => Rc::new(RwLock::new(connection)),
Err(e) => panic!("Failed to connect profile database: {e}"),
},
}
}
// Getters
pub fn connection(&self) -> &Rc<RwLock<Connection>> {
&self.connection
}
}
Loading…
Cancel
Save