merge the filtered deck errors into an enum
Fixes the wrong message being shown when trying to move cards to a filtered deck
This commit is contained in:
parent
7df128a103
commit
ac1b9fadde
@ -50,18 +50,14 @@ class ExistsError(Exception):
|
||||
|
||||
|
||||
class DeckRenameError(Exception):
|
||||
"""Legacy error, use DeckIsFilteredError instead."""
|
||||
"""Legacy error, use FilteredDeckError instead."""
|
||||
|
||||
def __init__(self, description: str, *args: object) -> None:
|
||||
super().__init__(description, *args)
|
||||
self.description = description
|
||||
|
||||
|
||||
class DeckIsFilteredError(StringError, DeckRenameError):
|
||||
pass
|
||||
|
||||
|
||||
class FilteredDeckEmpty(StringError):
|
||||
class FilteredDeckError(StringError, DeckRenameError):
|
||||
pass
|
||||
|
||||
|
||||
@ -95,10 +91,8 @@ def backend_exception_to_pylib(err: _pb.BackendError) -> Exception:
|
||||
return NotFoundError()
|
||||
elif val == "exists":
|
||||
return ExistsError()
|
||||
elif val == "deck_is_filtered":
|
||||
return DeckIsFilteredError(err.localized)
|
||||
elif val == "filtered_deck_empty":
|
||||
return FilteredDeckEmpty(err.localized)
|
||||
elif val == "filtered_deck_error":
|
||||
return FilteredDeckError(err.localized)
|
||||
elif val == "proto_error":
|
||||
return StringError(err.localized)
|
||||
elif val == "search_error":
|
||||
|
@ -568,9 +568,8 @@ message BackendError {
|
||||
string proto_error = 10;
|
||||
Empty not_found_error = 11;
|
||||
Empty exists = 12;
|
||||
Empty deck_is_filtered = 13;
|
||||
Empty filtered_deck_empty = 14;
|
||||
Empty search_error = 15;
|
||||
Empty filtered_deck_error = 13;
|
||||
Empty search_error = 14;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,10 @@ pub(super) fn anki_error_to_proto_error(err: AnkiError, tr: &I18n) -> pb::Backen
|
||||
AnkiError::ProtoError(info) => V::ProtoError(info),
|
||||
AnkiError::NotFound => V::NotFoundError(pb::Empty {}),
|
||||
AnkiError::Existing => V::Exists(pb::Empty {}),
|
||||
AnkiError::DeckIsFiltered => V::DeckIsFiltered(pb::Empty {}),
|
||||
AnkiError::FilteredDeckError(_) => V::FilteredDeckError(pb::Empty {}),
|
||||
AnkiError::SearchError(_) => V::SearchError(pb::Empty {}),
|
||||
AnkiError::TemplateSaveError { .. } => V::TemplateParse(pb::Empty {}),
|
||||
AnkiError::ParseNumError => V::InvalidInput(pb::Empty {}),
|
||||
AnkiError::FilteredDeckEmpty => V::FilteredDeckEmpty(pb::Empty {}),
|
||||
AnkiError::InvalidRegex(_) => V::InvalidInput(pb::Empty {}),
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
pub(crate) mod undo;
|
||||
|
||||
use crate::error::{AnkiError, Result};
|
||||
use crate::error::{AnkiError, FilteredDeckError, Result};
|
||||
use crate::notes::NoteId;
|
||||
use crate::{
|
||||
collection::Collection, config::SchedulerVersion, prelude::*, timestamp::TimestampSecs,
|
||||
@ -234,7 +234,7 @@ impl Collection {
|
||||
pub fn set_deck(&mut self, cards: &[CardId], deck_id: DeckId) -> Result<OpOutput<()>> {
|
||||
let deck = self.get_deck(deck_id)?.ok_or(AnkiError::NotFound)?;
|
||||
if deck.is_filtered() {
|
||||
return Err(AnkiError::DeckIsFiltered);
|
||||
return Err(FilteredDeckError::CanNotMoveCardsInto.into());
|
||||
}
|
||||
self.storage.set_search_table_to_card_ids(cards, false)?;
|
||||
let sched = self.scheduler_version();
|
||||
|
@ -12,14 +12,17 @@ pub use crate::backend_proto::{
|
||||
filtered_deck::{search_term::Order as FilteredSearchOrder, SearchTerm as FilteredSearchTerm},
|
||||
Deck as DeckProto, DeckCommon, DeckKind as DeckKindProto, FilteredDeck, NormalDeck,
|
||||
};
|
||||
use crate::{backend_proto as pb, markdown::render_markdown, text::sanitize_html_no_images};
|
||||
use crate::{
|
||||
backend_proto as pb,
|
||||
collection::Collection,
|
||||
deckconf::DeckConfId,
|
||||
define_newtype,
|
||||
error::FilteredDeckError,
|
||||
error::{AnkiError, Result},
|
||||
markdown::render_markdown,
|
||||
prelude::*,
|
||||
text::normalize_to_nfc,
|
||||
text::sanitize_html_no_images,
|
||||
timestamp::TimestampSecs,
|
||||
types::Usn,
|
||||
};
|
||||
@ -421,7 +424,7 @@ impl Collection {
|
||||
let child_split: Vec<_> = deck.name.split('\x1f').collect();
|
||||
if let Some(parent_deck) = self.first_existing_parent(&deck.name, 0)? {
|
||||
if parent_deck.is_filtered() {
|
||||
return Err(AnkiError::DeckIsFiltered);
|
||||
return Err(FilteredDeckError::MustBeLeafNode.into());
|
||||
}
|
||||
let parent_count = parent_deck.name.matches('\x1f').count() + 1;
|
||||
let need_create = parent_count != child_split.len() - 1;
|
||||
@ -654,7 +657,7 @@ impl Collection {
|
||||
if let Some(target) = new_parent {
|
||||
if let Some(target) = self.storage.get_deck(target)? {
|
||||
if target.is_filtered() {
|
||||
return Err(AnkiError::DeckIsFiltered);
|
||||
return Err(FilteredDeckError::MustBeLeafNode.into());
|
||||
}
|
||||
target_deck = target;
|
||||
target_name = Some(target_deck.name.as_str());
|
||||
|
32
rslib/src/error/filtered.rs
Normal file
32
rslib/src/error/filtered.rs
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use anki_i18n::I18n;
|
||||
|
||||
use super::AnkiError;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum FilteredDeckError {
|
||||
MustBeLeafNode,
|
||||
CanNotMoveCardsInto,
|
||||
SearchReturnedNoCards,
|
||||
}
|
||||
|
||||
impl FilteredDeckError {
|
||||
pub fn localized_description(&self, tr: &I18n) -> String {
|
||||
match self {
|
||||
FilteredDeckError::MustBeLeafNode => tr.errors_filtered_parent_deck(),
|
||||
FilteredDeckError::CanNotMoveCardsInto => {
|
||||
tr.browsing_cards_cant_be_manually_moved_into()
|
||||
}
|
||||
FilteredDeckError::SearchReturnedNoCards => tr.decks_filtered_deck_search_empty(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FilteredDeckError> for AnkiError {
|
||||
fn from(e: FilteredDeckError) -> Self {
|
||||
AnkiError::FilteredDeckError(e)
|
||||
}
|
||||
}
|
@ -2,11 +2,13 @@
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
mod db;
|
||||
mod filtered;
|
||||
mod network;
|
||||
mod search;
|
||||
|
||||
pub use {
|
||||
db::{DbError, DbErrorKind},
|
||||
filtered::FilteredDeckError,
|
||||
network::{NetworkError, NetworkErrorKind, SyncError, SyncErrorKind},
|
||||
search::{ParseError, SearchErrorKind},
|
||||
};
|
||||
@ -34,9 +36,8 @@ pub enum AnkiError {
|
||||
CollectionAlreadyOpen,
|
||||
NotFound,
|
||||
Existing,
|
||||
DeckIsFiltered,
|
||||
FilteredDeckError(FilteredDeckError),
|
||||
SearchError(SearchErrorKind),
|
||||
FilteredDeckEmpty,
|
||||
InvalidRegex(String),
|
||||
}
|
||||
|
||||
@ -73,8 +74,7 @@ impl AnkiError {
|
||||
}
|
||||
}
|
||||
AnkiError::ParseNumError => tr.errors_parse_number_fail().into(),
|
||||
AnkiError::DeckIsFiltered => tr.errors_filtered_parent_deck().into(),
|
||||
AnkiError::FilteredDeckEmpty => tr.decks_filtered_deck_search_empty().into(),
|
||||
AnkiError::FilteredDeckError(err) => err.localized_description(tr),
|
||||
_ => format!("{:?}", self),
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use std::convert::{TryFrom, TryInto};
|
||||
use crate::{
|
||||
config::ConfigKey,
|
||||
decks::{human_deck_name_to_native, FilteredDeck, FilteredSearchTerm},
|
||||
error::FilteredDeckError,
|
||||
search::writer::{deck_search, normalize_search},
|
||||
};
|
||||
use crate::{
|
||||
@ -176,7 +177,7 @@ impl Collection {
|
||||
|
||||
// if it failed to match any cards, we revert the changes
|
||||
if count == 0 {
|
||||
Err(AnkiError::FilteredDeckEmpty)
|
||||
Err(FilteredDeckError::SearchReturnedNoCards.into())
|
||||
} else {
|
||||
// update current deck and return id
|
||||
self.set_config(ConfigKey::CurrentDeckId, &deck.id)?;
|
||||
|
Loading…
Reference in New Issue
Block a user