From d2ebfc54825b6b70bcb9d731bd452de770266870 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 6 Mar 2021 15:31:12 +1000 Subject: [PATCH] move card undo into separate file --- rslib/src/{card.rs => card/mod.rs} | 100 ++------------------------- rslib/src/card/undo.rs | 104 +++++++++++++++++++++++++++++ rslib/src/notes.rs | 2 +- rslib/src/{undo.rs => undo/mod.rs} | 0 4 files changed, 111 insertions(+), 95 deletions(-) rename rslib/src/{card.rs => card/mod.rs} (68%) create mode 100644 rslib/src/card/undo.rs rename rslib/src/{undo.rs => undo/mod.rs} (100%) diff --git a/rslib/src/card.rs b/rslib/src/card/mod.rs similarity index 68% rename from rslib/src/card.rs rename to rslib/src/card/mod.rs index b3ab66b1b..f4eefdcbc 100644 --- a/rslib/src/card.rs +++ b/rslib/src/card/mod.rs @@ -1,6 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +mod undo; + use crate::define_newtype; use crate::err::{AnkiError, Result}; use crate::notes::NoteID; @@ -8,6 +10,7 @@ use crate::{ collection::Collection, config::SchedulerVersion, timestamp::TimestampSecs, types::Usn, undo::Undo, }; + use crate::{deckconf::DeckConf, decks::DeckID}; use num_enum::TryFromPrimitive; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -124,55 +127,6 @@ impl Card { } } -#[derive(Debug)] -pub(crate) struct CardAdded(Card); - -impl Undo for CardAdded { - fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { - col.remove_card_for_undo(self.0) - } -} - -#[derive(Debug)] -pub(crate) struct CardRemoved(Card); - -impl Undo for CardRemoved { - fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { - col.add_card_for_undo(self.0) - } -} - -#[derive(Debug)] -pub(crate) struct CardGraveAdded(CardID, Usn); - -impl Undo for CardGraveAdded { - fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { - col.remove_card_grave_for_undo(self.0, self.1) - } -} - -#[derive(Debug)] -pub(crate) struct CardGraveRemoved(CardID, Usn); - -impl Undo for CardGraveRemoved { - fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { - col.add_card_grave(self.0, self.1) - } -} - -#[derive(Debug)] -pub(crate) struct CardUpdated(Card); - -impl Undo for CardUpdated { - fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { - let current = col - .storage - .get_card(self.0.id)? - .ok_or_else(|| AnkiError::invalid_input("card disappeared"))?; - col.update_card_inner(&mut self.0.clone(), ¤t) - } -} - impl Card { pub fn new(note_id: NoteID, template_idx: u16, deck_id: DeckID, due: i32) -> Self { Card { @@ -204,15 +158,7 @@ impl Collection { /// Marks the card as modified, then saves it. pub(crate) fn update_card(&mut self, card: &mut Card, original: &Card, usn: Usn) -> Result<()> { card.set_modified(usn); - self.update_card_inner(card, original) - } - - pub(crate) fn update_card_inner(&mut self, card: &mut Card, original: &Card) -> Result<()> { - if card.id.0 == 0 { - return Err(AnkiError::invalid_input("card id not set")); - } - self.save_undo(Box::new(CardUpdated(original.clone()))); - self.storage.update_card(card) + self.update_card_undoable(card, original) } pub(crate) fn add_card(&mut self, card: &mut Card) -> Result<()> { @@ -221,16 +167,7 @@ impl Collection { } card.mtime = TimestampSecs::now(); card.usn = self.usn()?; - self.storage.add_card(card)?; - self.save_undo(Box::new(CardAdded(card.clone()))); - Ok(()) - } - - /// Used for undoing - fn add_card_for_undo(&mut self, card: Card) -> Result<()> { - self.storage.add_or_update_card(&card)?; - self.save_undo(Box::new(CardAdded(card))); - Ok(()) + self.add_card_undoable(card) } /// Remove cards and any resulting orphaned notes. @@ -241,7 +178,7 @@ impl Collection { for cid in cids { if let Some(card) = self.storage.get_card(*cid)? { nids.insert(card.note_id); - self.remove_card_only(card, usn)?; + self.remove_card_and_add_grave_undoable(card, usn)?; } } for nid in nids { @@ -253,31 +190,6 @@ impl Collection { Ok(()) } - pub(crate) fn remove_card_only(&mut self, card: Card, usn: Usn) -> Result<()> { - self.add_card_grave(card.id, usn)?; - self.storage.remove_card(card.id)?; - self.save_undo(Box::new(CardRemoved(card))); - - Ok(()) - } - - /// Only used when undoing; does not add a grave. - fn remove_card_for_undo(&mut self, card: Card) -> Result<()> { - self.storage.remove_card(card.id)?; - self.save_undo(Box::new(CardRemoved(card))); - Ok(()) - } - - fn add_card_grave(&mut self, cid: CardID, usn: Usn) -> Result<()> { - self.save_undo(Box::new(CardGraveAdded(cid, usn))); - self.storage.add_card_grave(cid, usn) - } - - fn remove_card_grave_for_undo(&mut self, cid: CardID, usn: Usn) -> Result<()> { - self.save_undo(Box::new(CardGraveRemoved(cid, usn))); - self.storage.remove_card_grave(cid) - } - pub fn set_deck(&mut self, cards: &[CardID], deck_id: DeckID) -> Result<()> { let deck = self.get_deck(deck_id)?.ok_or(AnkiError::NotFound)?; if deck.is_filtered() { diff --git a/rslib/src/card/undo.rs b/rslib/src/card/undo.rs new file mode 100644 index 000000000..685ca776c --- /dev/null +++ b/rslib/src/card/undo.rs @@ -0,0 +1,104 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + +use super::Undo; +use crate::prelude::*; + +#[derive(Debug)] +pub(crate) struct CardAdded(Card); + +impl Undo for CardAdded { + fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { + col.remove_card_only(self.0) + } +} + +#[derive(Debug)] +pub(crate) struct CardRemoved(Card); + +impl Undo for CardRemoved { + fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { + col.readd_deleted_card(self.0) + } +} + +#[derive(Debug)] +pub(crate) struct CardGraveAdded(CardID, Usn); + +impl Undo for CardGraveAdded { + fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { + col.remove_card_grave(self.0, self.1) + } +} + +#[derive(Debug)] +pub(crate) struct CardGraveRemoved(CardID, Usn); + +impl Undo for CardGraveRemoved { + fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { + col.add_card_grave_undoable(self.0, self.1) + } +} + +#[derive(Debug)] +pub(crate) struct CardUpdated(Card); + +impl Undo for CardUpdated { + fn undo(self: Box, col: &mut crate::collection::Collection) -> Result<()> { + let current = col + .storage + .get_card(self.0.id)? + .ok_or_else(|| AnkiError::invalid_input("card disappeared"))?; + col.update_card_undoable(&mut self.0.clone(), ¤t) + } +} + +impl Collection { + pub(super) fn add_card_undoable(&mut self, card: &mut Card) -> Result<(), AnkiError> { + self.storage.add_card(card)?; + self.save_undo(Box::new(CardAdded(card.clone()))); + Ok(()) + } + + pub(super) fn update_card_undoable(&mut self, card: &mut Card, original: &Card) -> Result<()> { + if card.id.0 == 0 { + return Err(AnkiError::invalid_input("card id not set")); + } + self.save_undo(Box::new(CardUpdated(original.clone()))); + self.storage.update_card(card) + } + + pub(crate) fn remove_card_and_add_grave_undoable( + &mut self, + card: Card, + usn: Usn, + ) -> Result<()> { + self.add_card_grave_undoable(card.id, usn)?; + self.storage.remove_card(card.id)?; + self.save_undo(Box::new(CardRemoved(card))); + + Ok(()) + } + + fn add_card_grave_undoable(&mut self, cid: CardID, usn: Usn) -> Result<()> { + self.save_undo(Box::new(CardGraveAdded(cid, usn))); + self.storage.add_card_grave(cid, usn) + } + + fn readd_deleted_card(&mut self, card: Card) -> Result<()> { + self.storage.add_or_update_card(&card)?; + self.save_undo(Box::new(CardAdded(card))); + Ok(()) + } + + fn remove_card_only(&mut self, card: Card) -> Result<()> { + self.storage.remove_card(card.id)?; + self.save_undo(Box::new(CardRemoved(card))); + Ok(()) + } + + fn remove_card_grave(&mut self, cid: CardID, usn: Usn) -> Result<()> { + self.save_undo(Box::new(CardGraveRemoved(cid, usn))); + self.storage.remove_card_grave(cid) + } +} diff --git a/rslib/src/notes.rs b/rslib/src/notes.rs index cca83051a..e5a8de5ca 100644 --- a/rslib/src/notes.rs +++ b/rslib/src/notes.rs @@ -437,7 +437,7 @@ impl Collection { let nid = *nid; if let Some(_existing_note) = col.storage.get_note(nid)? { for card in col.storage.all_cards_of_note(nid)? { - col.remove_card_only(card, usn)?; + col.remove_card_and_add_grave_undoable(card, usn)?; } col.remove_note_only(nid, usn)?; } diff --git a/rslib/src/undo.rs b/rslib/src/undo/mod.rs similarity index 100% rename from rslib/src/undo.rs rename to rslib/src/undo/mod.rs