diff --git a/Cargo.lock b/Cargo.lock index 981fcdc..b48e740 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1166,20 +1166,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "decimal" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a8ab77e91baeb15034c3be91e87bff4665c9036216148e4996d9a9f5792114d" -dependencies = [ - "bitflags 1.3.2", - "cc", - "libc", - "ord_subset", - "rustc-serialize", - "serde", -] - [[package]] name = "der" version = "0.7.10" @@ -3270,12 +3256,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "ord_subset" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdcf5505c0f054ce51fa0fa74142738930a45d5ac1faacae4dd4e2f54afe00fa" - [[package]] name = "ordered-float" version = "4.6.0" @@ -3301,14 +3281,15 @@ version = "0.1.0" dependencies = [ "async-trait", "chrono", - "decimal", "migration", + "rust_decimal", "sea-orm", "serde", "serde_json", "tauri", "tauri-build", "tauri-plugin-opener", + "thiserror 2.0.18", ] [[package]] @@ -4007,12 +3988,6 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" -[[package]] -name = "rustc-serialize" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" - [[package]] name = "rustc_version" version = "0.4.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index c9b6780..6b7f9dd 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -3,7 +3,7 @@ name = "otter" version = "0.1.0" description = "A Tauri App" authors = ["you"] -edition = "2021" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -23,9 +23,10 @@ tauri-plugin-opener = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" async-trait = "0.1.89" -decimal = "2.1.0" +rust_decimal = "1.42.0" sea-orm.workspace = true migration = { path = "../crates/migration" } chrono.workspace = true +thiserror = "2.0.18" diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 7b42cf3..d41d0a1 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -12,6 +12,7 @@ use tauri::Manager; use crate::services::create_services; +mod commands; mod db; mod services; @@ -27,8 +28,31 @@ pub fn run() { tauri::Builder::default() .setup(|app| { tauri::async_runtime::block_on(async { - let mut connect_options = - ConnectOptions::new("sqlite://finance_manager.db".to_string()); + // Get the app's data directory + let app_data_dir = app + .path() + .app_data_dir() + .expect("Failed to get app data directory"); + + // Create the directory if it doesn't exist + std::fs::create_dir_all(&app_data_dir) + .expect("Failed to create app data directory"); + + // Construct the database path + let db_path = app_data_dir.join("finance_manager.db"); + + // Ensure the database file exists + if !db_path.exists() { + std::fs::File::create(&db_path).expect("Failed to create database file"); + } + + // Get the canonical path + let canonical_path = db_path + .canonicalize() + .expect("Failed to get canonical path"); + let db_url = format!("sqlite://{}", canonical_path.to_string_lossy()); + + let mut connect_options = ConnectOptions::new(db_url); connect_options.after_connect(|conn| { Box::pin(async move { // Enable foreign key support for SQLite @@ -50,12 +74,22 @@ pub fn run() { migration::Migrator::up(&db, None) .await .expect("Failed to run migrations"); - app.manage(create_services(db)) + + let services = create_services(db); + app.manage(services) }); Ok(()) }) .plugin(tauri_plugin_opener::init()) - .invoke_handler(tauri::generate_handler![greet]) + .invoke_handler(tauri::generate_handler![ + greet, + commands::get_account, + commands::get_accounts, + commands::create_account, + commands::get_transactions_for_account, + commands::create_transaction, + commands::update_transaction + ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src-tauri/src/services/mod.rs b/src-tauri/src/services/mod.rs index 7b00bcb..32b7087 100644 --- a/src-tauri/src/services/mod.rs +++ b/src-tauri/src/services/mod.rs @@ -2,22 +2,65 @@ use std::sync::Arc; use sea_orm::DatabaseConnection; -pub mod accounts; +use crate::services::{ + accounts::{ + AccountsService, AccountsServiceImpl, + category::{AccountCategoryService, AccountCategoryServiceImpl}, + }, + transaction::{ + TransactionService, TransactionServiceImpl, + category::{CategoryService, CategoryServiceImpl}, + tag::{TagService, TagServiceImpl}, + }, +}; -pub struct Services { - pub account_category: Arc, - pub accounts: Arc, +pub mod accounts; +pub mod transaction; + +pub type AppState = Services< + dyn AccountCategoryService, + dyn AccountsService, + dyn TransactionService, + dyn CategoryService, + dyn TagService, +>; + +#[derive(Clone)] +pub struct Services +where + AC: AccountCategoryService + ?Sized, + A: AccountsService + ?Sized, + T: TransactionService + ?Sized, + TC: CategoryService + ?Sized, + TT: TagService + ?Sized, +{ + pub account_category: Arc, + pub accounts: Arc, + pub transaction: Arc, + pub transaction_category: Arc, + pub transaction_tag: Arc, } -pub fn create_services(db: DatabaseConnection) -> Services { - let account_category_service = Arc::new(accounts::category::AccountCategoryServiceImpl::new( +pub fn create_services(db: DatabaseConnection) -> AppState { + let account_category_service: Arc = + Arc::new(AccountCategoryServiceImpl::new(db.clone())); + let account_service: Arc = Arc::new(AccountsServiceImpl::new( db.clone(), + Arc::new(AccountCategoryServiceImpl::new(db.clone())), )); + let transaction_category_service: Arc = + Arc::new(CategoryServiceImpl::new(db.clone())); + let transaction_tag_service: Arc = Arc::new(TagServiceImpl::new(db.clone())); Services { account_category: account_category_service.clone(), - accounts: Arc::new(accounts::AccountsServiceImpl::new( - db, - account_category_service, - )), + accounts: account_service.clone(), + transaction: Arc::new(TransactionServiceImpl::new( + db.clone(), + account_service.clone(), + transaction_category_service.clone(), + transaction_tag_service.clone(), + )) as Arc, + transaction_category: transaction_category_service, + transaction_tag: transaction_tag_service, } }