summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src
diff options
context:
space:
mode:
Diffstat (limited to 'schist_desktop_gui/src')
-rw-r--r--schist_desktop_gui/src/connection.rs20
-rw-r--r--schist_desktop_gui/src/dummy_data.rs70
-rw-r--r--schist_desktop_gui/src/gui.rs47
-rw-r--r--schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs6
-rw-r--r--schist_desktop_gui/src/gui/components/transactions_view.rs2
-rw-r--r--schist_desktop_gui/src/main.rs32
6 files changed, 83 insertions, 94 deletions
diff --git a/schist_desktop_gui/src/connection.rs b/schist_desktop_gui/src/connection.rs
new file mode 100644
index 0000000..5a88083
--- /dev/null
+++ b/schist_desktop_gui/src/connection.rs
@@ -0,0 +1,20 @@
+use std::{fs::create_dir_all, path::Path};
+
+use anyhow::Context;
+use diesel::{Connection, SqliteConnection};
+
+const SCHIST_DATA_DIR: &'static str = "schist";
+const SCHIST_DATABASE_FILENAME: &'static str = "schist.sqlite";
+
+pub fn establish_connection() -> anyhow::Result<SqliteConnection> {
+ let data_dir = dirs::data_dir().context("Failed to get local app data directory")?;
+ let schist_local_dir = data_dir.join(Path::new(SCHIST_DATA_DIR));
+ create_dir_all(&schist_local_dir)
+ .context(format!("Failed to create local files directory at {}", schist_local_dir.display()))?;
+ let db_path = schist_local_dir.join(Path::new(SCHIST_DATABASE_FILENAME));
+ let db_path = db_path
+ .to_str()
+ .context("Failed to construct database path")?;
+ Ok(SqliteConnection::establish(db_path)
+ .with_context(|| format!("Failed to connect to database at {}", db_path))?)
+}
diff --git a/schist_desktop_gui/src/dummy_data.rs b/schist_desktop_gui/src/dummy_data.rs
deleted file mode 100644
index 079b687..0000000
--- a/schist_desktop_gui/src/dummy_data.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use schist_models::{
- account::Account, bucket::Bucket, budget_period_unit::BudgetPeriodUnit, date_utc::DateUtc,
-};
-
-#[derive(Clone, Debug)]
-pub struct Error {}
-
-impl From<anyhow::Error> for Error {
- fn from(_value: anyhow::Error) -> Self {
- Error {}
- }
-}
-
-pub async fn fetch_accounts() -> Result<Vec<Account>, Error> {
- Ok(vec![
- Account {
- id: 0,
- name: String::from("Nationwide current account"),
- opening_balance: 0,
- opening_date: DateUtc::from_ymd(2024, 06, 12)?,
- },
- Account {
- id: 1,
- name: String::from("cash account"),
- opening_balance: 0,
- opening_date: DateUtc::from_ymd(2024, 06, 12)?,
- },
- Account {
- id: 2,
- name: String::from("YBS savings account"),
- opening_balance: 0,
- opening_date: DateUtc::from_ymd(2024, 06, 12)?,
- },
- ])
-}
-
-pub async fn fetch_buckets() -> Result<Vec<Bucket>, Error> {
- Ok(vec![
- Bucket {
- id: 0,
- name: String::from("groceries"),
- balance: 123,
- balance_date: DateUtc::from_ymd(2025, 8, 10)?,
- budget_period: 1,
- budget_period_unit: BudgetPeriodUnit::Month,
- budget_quantity: 300,
- group: String::from("normal expenses"),
- },
- Bucket {
- id: 1,
- name: String::from("outdoor trips"),
- balance: -11,
- balance_date: DateUtc::from_ymd(2025, 8, 10)?,
- budget_period: 1,
- budget_period_unit: BudgetPeriodUnit::Month,
- budget_quantity: 110,
- group: String::from("outdoors"),
- },
- Bucket {
- id: 2,
- name: String::from("salary"),
- balance: 1018,
- balance_date: DateUtc::from_ymd(2025, 8, 10)?,
- budget_period: 1,
- budget_period_unit: BudgetPeriodUnit::Month,
- budget_quantity: -2196,
- group: String::from("income"),
- },
- ])
-}
diff --git a/schist_desktop_gui/src/gui.rs b/schist_desktop_gui/src/gui.rs
index 0f84f41..d22e999 100644
--- a/schist_desktop_gui/src/gui.rs
+++ b/schist_desktop_gui/src/gui.rs
@@ -1,12 +1,13 @@
pub mod components;
pub mod screens;
+use diesel::SqliteConnection;
use iced::Element;
use schist_models::{account::Account, bucket::Bucket};
+use schist_queries::{accounts::get_all_accounts, buckets::get_all_buckets};
use crate::{
config::Config,
- dummy_data::{self, fetch_accounts, fetch_buckets},
gui::screens::{main_screen, MainScreen, Screen},
shortcut::KeyBind,
traits::{Component, Viewable},
@@ -16,8 +17,23 @@ use crate::{
pub enum Message {
Event(iced::Event),
MainScreenMessage(main_screen::Message),
- RefetchedAccounts(Result<Vec<Account>, dummy_data::Error>),
- RefetchedBuckets(Result<Vec<Bucket>, dummy_data::Error>),
+ RefetchedAccounts(FetchResult<Vec<Account>>),
+ RefetchedBuckets(FetchResult<Vec<Bucket>>),
+}
+
+pub type FetchResult<T> = std::result::Result<T, FetchError>;
+
+#[derive(Clone, Debug)]
+pub struct FetchError {
+ pub message: String,
+}
+
+impl FetchError {
+ pub fn new(err: anyhow::Error) -> Self {
+ Self {
+ message: format!("{}", err),
+ }
+ }
}
pub struct Gui {
@@ -28,25 +44,30 @@ pub struct Gui {
}
impl Gui {
- pub fn new() -> (Self, iced::Task<Message>) {
- let tasks = vec![
- iced::Task::perform(fetch_buckets(), Message::RefetchedBuckets),
- iced::Task::perform(fetch_accounts(), Message::RefetchedAccounts),
- ];
+ pub fn new(connection: &mut SqliteConnection) -> (Self, iced::Task<Message>) {
let buckets = Vec::new();
let accounts = Vec::new();
- let gui = Self {
+ let mut gui = Self {
active_screen: Screen::Main,
buckets: buckets.clone(),
main_screen: MainScreen::new(buckets, accounts),
config: Config::default(),
};
- (gui, iced::Task::batch(tasks))
+
+ let buckets = get_all_buckets(connection).map_err(FetchError::new);
+ let accounts = get_all_accounts(connection).map_err(FetchError::new);
+
+ let tasks = iced::Task::batch(vec![
+ gui.update(Message::RefetchedBuckets(buckets)),
+ gui.update(Message::RefetchedAccounts(accounts)),
+ ]);
+
+ (gui, tasks)
}
}
impl Gui {
- pub fn view(&self) -> Element<Message> {
+ pub fn view<'a>(&'a self) -> Element<'a, Message> {
match self.active_screen {
Screen::Main => self.main_screen.view().map(Message::MainScreenMessage),
}
@@ -109,7 +130,7 @@ impl Gui {
self.main_screen
.update(main_screen::Message::SetBuckets(buckets));
}
- Err(err) => println!("Failed to get buckets: {:?}", err),
+ Err(err) => println!("Failed to get buckets: {:?}", err.message),
};
iced::Task::none()
}
@@ -119,7 +140,7 @@ impl Gui {
self.main_screen
.update(main_screen::Message::SetAccounts(accounts));
}
- Err(err) => println!("Failed to get accounts: {:?}", err),
+ Err(err) => println!("Failed to get accounts: {:?}", err.message),
}
iced::Task::none()
}
diff --git a/schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs b/schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs
index fa2dcac..b31e0e2 100644
--- a/schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs
+++ b/schist_desktop_gui/src/gui/components/bucket_name_and_balance.rs
@@ -19,6 +19,10 @@ impl BucketNameAndBalance {
impl<'a> Into<Element<'a, navigation::Message<BucketNameAndBalance>>> for BucketNameAndBalance {
fn into(self) -> Element<'a, navigation::Message<BucketNameAndBalance>> {
- row![text(self.bucket.name.clone()), text(self.bucket.balance)].into()
+ row![
+ text(self.bucket.name.clone()),
+ text(self.bucket.balance.unwrap_or(0))
+ ]
+ .into()
}
}
diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs
index 6181a14..3a8333c 100644
--- a/schist_desktop_gui/src/gui/components/transactions_view.rs
+++ b/schist_desktop_gui/src/gui/components/transactions_view.rs
@@ -43,7 +43,7 @@ impl TransactionsView {
}
impl<'a> Viewable<'a, Message> for TransactionsView {
- fn view(&self) -> Element<Message> {
+ fn view(&'a self) -> Element<'a, Message> {
let navigation = self.navigation.view().map(Message::NavigationMessage);
let main_content = column![iced::widget::text(self.greeting.clone())];
row![
diff --git a/schist_desktop_gui/src/main.rs b/schist_desktop_gui/src/main.rs
index 7e54ddb..24aedc0 100644
--- a/schist_desktop_gui/src/main.rs
+++ b/schist_desktop_gui/src/main.rs
@@ -1,5 +1,5 @@
mod config;
-mod dummy_data;
+mod connection;
mod gui;
mod settings;
mod shortcut;
@@ -8,17 +8,31 @@ mod theme;
mod traits;
mod window_settings;
+use anyhow::Context;
+use diesel_migrations::MigrationHarness;
+use schist_schema::migrations::MIGRATIONS;
+
use crate::{
- config::Config, gui::Gui, settings::make_settings, theme::make_theme,
+ config::Config,
+ connection::establish_connection,
+ gui::Gui,
+ settings::make_settings,
+ theme::make_theme,
window_settings::make_window_settings,
};
-fn main() -> iced::Result {
+fn main() -> anyhow::Result<()> {
let config = Config::default();
- iced::application("Schist", Gui::update, Gui::view)
- .settings(make_settings(&config.clone()))
- .subscription(gui::subscription)
- .theme(make_theme)
- .window(make_window_settings(&config.clone()))
- .run_with(Gui::new)
+ let mut connection = establish_connection()
+ .context("Failed to establish database connection")?;
+ connection.run_pending_migrations(MIGRATIONS)
+ .expect("Failed to run pending database migrations");
+
+iced::application("Schist", Gui::update, Gui::view)
+ .settings(make_settings(&config.clone()))
+ .subscription(gui::subscription)
+ .theme(make_theme)
+ .window(make_window_settings(&config.clone()))
+ .run_with(move || Gui::new(&mut connection))
+ .context("Failed to run Schist GUI")
}