diff --git a/src/app.rs b/src/app.rs index f6f66a1..aec8db7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -95,7 +95,7 @@ pub fn fill_state(state: &mut AppState) { let setting = load_settings(&state.connection); state.dictionary = list; - state.decks = sets; + state.decks = sets.unwrap_or_default(); state.word_groups = groups; state.sync_data = setting } diff --git a/src/data_provider/card_sets.rs b/src/data_provider/card_sets.rs index de6e569..ef82bcb 100644 --- a/src/data_provider/card_sets.rs +++ b/src/data_provider/card_sets.rs @@ -2,11 +2,13 @@ use crate::core::srs::OrderMode; use crate::data::entities::DeckSettings; use rusqlite::Connection; +use crate::notification::NotificationData; +use crate::notification::NotificationData::{DbLoadError, DbSaveError}; -pub fn load_sets(connection: &Connection) -> Vec { +pub fn load_sets(connection: &Connection) -> Result, NotificationData> { let mut stmt = connection .prepare("SELECT id, name, forward, backward, filter FROM card_set") - .unwrap(); + .expect("Failed to prepare state query"); let iter = stmt .query_map([], |row| { Ok(DeckSettings { @@ -19,17 +21,17 @@ pub fn load_sets(connection: &Connection) -> Vec { open_mode: OrderMode::Default, }) }) - .unwrap(); + .map_err(|_| DbLoadError)?; let mut buffer = vec![]; - for word in iter { - buffer.push(word.unwrap()); + for word in iter.filter_map(|result| result.ok()) { + buffer.push(word); } - buffer + Ok(buffer) } -pub fn add_set(set: &mut DeckSettings, connection: &Connection) { +pub fn add_set(set: &mut DeckSettings, connection: &Connection) -> Result<(), NotificationData> { let index : u32 = connection .query_row( "INSERT INTO card_set (name, forward, backward, filter) VALUES (?1, ?2, ?3, ?4) RETURNING id", @@ -41,14 +43,15 @@ pub fn add_set(set: &mut DeckSettings, connection: &Connection) { ), |row| row.get(0) ) - .unwrap(); + .map_err(|_| DbSaveError)?; set.id = index.into(); + Ok(()) } -pub fn update_deck(set: &mut DeckSettings, connection: &Connection) { +pub fn update_deck(set: &mut DeckSettings, connection: &Connection) -> Result<(), NotificationData> { if !set.id.is_valid() { - add_set(set, connection); + add_set(set, connection)?; } else { connection .execute( @@ -61,15 +64,17 @@ pub fn update_deck(set: &mut DeckSettings, connection: &Connection) { &set.id ), ) - .unwrap(); + .map_err(|_| DbSaveError)?; } + Ok(()) } -pub fn delete_set(set: &DeckSettings, connection: &Connection) { +pub fn delete_set(set: &DeckSettings, connection: &Connection) -> Result<(), NotificationData> { if !set.id.is_valid() { - return; + return Err(DbSaveError); } connection .execute("DELETE FROM card_set WHERE id = ?1", (&set.id,)) - .unwrap(); + .map_err(|_| DbSaveError)?; + Ok(()) } diff --git a/src/navigation.rs b/src/navigation.rs index 66f3cfe..6c50c53 100644 --- a/src/navigation.rs +++ b/src/navigation.rs @@ -77,7 +77,8 @@ pub enum RootMessage { None, UpdateData, } - +#[allow(clippy::enum_variant_names)] +#[allow(clippy::large_enum_variant)] pub enum Page { Selector(SelectorState), Quiz(QuizState), diff --git a/src/notification.rs b/src/notification.rs index 5c65124..5e91855 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -157,6 +157,12 @@ impl NotificationManager { NotificationData::WebApiUnavailable => { text!("Не получается подключиться к Api") } + NotificationData::DbSaveError => { + text!("Не получается сохранить данные") + } + NotificationData::DbLoadError => { + text!("Не получается загрузить данные") + } } .width(Fill) .into() @@ -179,4 +185,6 @@ pub enum NotificationData { OpenFileError, VoiceVoxUnavailable, WebApiUnavailable, + DbSaveError, + DbLoadError, } diff --git a/src/pages/repetition_settings.rs b/src/pages/repetition_settings.rs index 62f5517..0fac784 100644 --- a/src/pages/repetition_settings.rs +++ b/src/pages/repetition_settings.rs @@ -1,8 +1,10 @@ - +use crate::app::AppState; +use crate::data::entities::DeckSettings; use crate::data_provider::card_sets::{delete_set, update_deck}; use crate::data_provider::card_stats::{delete_stats, load_stats_of_deck}; use crate::navigation::Page::PreviousPage; use crate::navigation::{NavigatedPage, Page, RootMessage}; +use crate::notification::NotificationRequest; use crate::pages::repetition_settings::RepetitionSettingsMessage::*; use crate::styling::*; use iced::widget::button::danger; @@ -10,12 +12,10 @@ use iced::widget::text_input::Catalog; use iced::widget::{button, column, row, scrollable, space, text, text_input}; use iced::{Element, Task}; use iced_core::Length::Fill; -use iced_core::{Padding, Theme, color}; +use iced_core::{color, Padding, Theme}; use parking_lot::Mutex; use std::sync::Arc; use std::time::Duration; -use crate::app::AppState; -use crate::data::entities::DeckSettings; pub struct RepetitionSettingsState { set: DeckSettings, @@ -61,7 +61,9 @@ impl NavigatedPage for RepetitionSettingsState { Back => {} Save => { let mut state = self.state.lock(); - update_deck(&mut self.set, &state.connection); + if let Err(e) = update_deck(&mut self.set, &state.connection) { + return Task::done(RootMessage::PushNotification(NotificationRequest::Error(e))); + } if self.filter_changed { update_deck_stats(&self.set, &state); } @@ -95,7 +97,10 @@ impl NavigatedPage for RepetitionSettingsState { }); } let mut state = self.state.lock(); - delete_set(&self.set, &state.connection); + if let Err(e) = delete_set(&self.set, &state.connection) { + return Task::done(RootMessage::PushNotification(NotificationRequest::Error(e))); + } + state.decks.remove(self.index); return Task::done(RootMessage::RepetitionSettings(Back)); } diff --git a/src/pages/repetitions.rs b/src/pages/repetitions.rs index 6fbcf31..4475acb 100644 --- a/src/pages/repetitions.rs +++ b/src/pages/repetitions.rs @@ -27,6 +27,7 @@ use iced_core::svg::Handle; use parking_lot::Mutex; use std::ops::Deref; use std::sync::Arc; +use crate::notification::NotificationRequest; #[derive(Clone)] pub struct RepetitionsState { @@ -146,7 +147,9 @@ impl NavigatedPage for RepetitionsState { let mut deck = self.selected_deck().unwrap().clone(); let mut state = self.state.lock(); { - update_deck(&mut deck.general_settings, &state.connection); + if let Err(e) = update_deck(&mut deck.general_settings, &state.connection){ + return Task::done(RootMessage::PushNotification(NotificationRequest::Error(e))) + } if let Some(index) = deck.index { state.decks[index] = deck.general_settings.clone(); } else {