Anki/rslib/src/card/undo.rs
Damien Elmes dc81a7fed0 use mixed case for abbreviations in Rust code
So, this is fun. Apparently "DeckId" is considered preferable to the
"DeckID" were were using until now, and the latest clippy will start
warning about it. We could of course disable the warning, but probably
better to bite the bullet and switch to the naming that's generally
considered best.
2021-03-27 19:53:33 +10:00

78 lines
2.8 KiB
Rust

// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use crate::prelude::*;
#[derive(Debug)]
pub(crate) enum UndoableCardChange {
Added(Box<Card>),
Updated(Box<Card>),
Removed(Box<Card>),
GraveAdded(Box<(CardId, Usn)>),
GraveRemoved(Box<(CardId, Usn)>),
}
impl Collection {
pub(crate) fn undo_card_change(&mut self, change: UndoableCardChange) -> Result<()> {
match change {
UndoableCardChange::Added(card) => self.remove_card_only(*card),
UndoableCardChange::Updated(mut card) => {
let current = self
.storage
.get_card(card.id)?
.ok_or_else(|| AnkiError::invalid_input("card disappeared"))?;
self.update_card_undoable(&mut *card, current)
}
UndoableCardChange::Removed(card) => self.restore_deleted_card(*card),
UndoableCardChange::GraveAdded(e) => self.remove_card_grave(e.0, e.1),
UndoableCardChange::GraveRemoved(e) => self.add_card_grave_undoable(e.0, e.1),
}
}
pub(super) fn add_card_undoable(&mut self, card: &mut Card) -> Result<(), AnkiError> {
self.storage.add_card(card)?;
self.save_undo(UndoableCardChange::Added(Box::new(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(UndoableCardChange::Updated(Box::new(original)));
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(UndoableCardChange::Removed(Box::new(card)));
Ok(())
}
fn restore_deleted_card(&mut self, card: Card) -> Result<()> {
self.storage.add_or_update_card(&card)?;
self.save_undo(UndoableCardChange::Added(Box::new(card)));
Ok(())
}
fn remove_card_only(&mut self, card: Card) -> Result<()> {
self.storage.remove_card(card.id)?;
self.save_undo(UndoableCardChange::Removed(Box::new(card)));
Ok(())
}
fn add_card_grave_undoable(&mut self, cid: CardId, usn: Usn) -> Result<()> {
self.save_undo(UndoableCardChange::GraveAdded(Box::new((cid, usn))));
self.storage.add_card_grave(cid, usn)
}
fn remove_card_grave(&mut self, cid: CardId, usn: Usn) -> Result<()> {
self.save_undo(UndoableCardChange::GraveRemoved(Box::new((cid, usn))));
self.storage.remove_card_grave(cid)
}
}