diff --git a/rslib/src/decks/mod.rs b/rslib/src/decks/mod.rs index 3330cb83b..557ab0b39 100644 --- a/rslib/src/decks/mod.rs +++ b/rslib/src/decks/mod.rs @@ -9,6 +9,7 @@ mod name; mod remove; mod reparent; mod schema11; +mod stats; mod tree; pub(crate) mod undo; @@ -20,8 +21,8 @@ pub use crate::backend_proto::{ Deck as DeckProto, }; use crate::{ - backend_proto as pb, define_newtype, error::FilteredDeckError, markdown::render_markdown, - prelude::*, text::sanitize_html_no_images, + define_newtype, error::FilteredDeckError, markdown::render_markdown, prelude::*, + text::sanitize_html_no_images, }; pub(crate) use counts::DueCounts; pub(crate) use name::{ @@ -63,17 +64,6 @@ impl Deck { } } - fn reset_stats_if_day_changed(&mut self, today: u32) { - let c = &mut self.common; - if c.last_day_studied != today { - c.new_studied = 0; - c.learning_studied = 0; - c.review_studied = 0; - c.milliseconds_studied = 0; - c.last_day_studied = today; - } - } - /// Returns deck config ID if deck is a normal deck. pub(crate) fn config_id(&self) -> Option { if let DeckKind::Normal(ref norm) = self.kind { @@ -177,74 +167,6 @@ impl Collection { let machine_name = human_deck_name_to_native(&human_name); self.storage.get_deck_id(&machine_name) } - - /// Apply input delta to deck, and its parents. - /// Caller should ensure transaction. - pub(crate) fn update_deck_stats( - &mut self, - today: u32, - usn: Usn, - input: pb::UpdateStatsIn, - ) -> Result<()> { - let did = input.deck_id.into(); - let mutator = |c: &mut DeckCommon| { - c.new_studied += input.new_delta; - c.review_studied += input.review_delta; - c.milliseconds_studied += input.millisecond_delta; - }; - if let Some(mut deck) = self.storage.get_deck(did)? { - self.update_deck_stats_single(today, usn, &mut deck, mutator)?; - for mut deck in self.storage.parent_decks(&deck)? { - self.update_deck_stats_single(today, usn, &mut deck, mutator)?; - } - } - Ok(()) - } - - /// Modify the deck's limits by adjusting the 'done today' count. - /// Positive values increase the limit, negative value decrease it. - /// Caller should ensure a transaction. - pub(crate) fn extend_limits( - &mut self, - today: u32, - usn: Usn, - did: DeckId, - new_delta: i32, - review_delta: i32, - ) -> Result<()> { - let mutator = |c: &mut DeckCommon| { - c.new_studied -= new_delta; - c.review_studied -= review_delta; - }; - if let Some(mut deck) = self.storage.get_deck(did)? { - self.update_deck_stats_single(today, usn, &mut deck, mutator)?; - for mut deck in self.storage.parent_decks(&deck)? { - self.update_deck_stats_single(today, usn, &mut deck, mutator)?; - } - for mut deck in self.storage.child_decks(&deck)? { - self.update_deck_stats_single(today, usn, &mut deck, mutator)?; - } - } - - Ok(()) - } - - fn update_deck_stats_single( - &mut self, - today: u32, - usn: Usn, - deck: &mut Deck, - mutator: F, - ) -> Result<()> - where - F: FnOnce(&mut DeckCommon), - { - let original = deck.clone(); - deck.reset_stats_if_day_changed(today); - mutator(&mut deck.common); - deck.set_modified(usn); - self.update_single_deck_undoable(deck, original) - } } #[cfg(test)] diff --git a/rslib/src/decks/stats.rs b/rslib/src/decks/stats.rs new file mode 100644 index 000000000..5eda8b0c9 --- /dev/null +++ b/rslib/src/decks/stats.rs @@ -0,0 +1,87 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +use super::DeckCommon; +use crate::{backend_proto as pb, prelude::*}; + +impl Deck { + pub(super) fn reset_stats_if_day_changed(&mut self, today: u32) { + let c = &mut self.common; + if c.last_day_studied != today { + c.new_studied = 0; + c.learning_studied = 0; + c.review_studied = 0; + c.milliseconds_studied = 0; + c.last_day_studied = today; + } + } +} + +impl Collection { + /// Apply input delta to deck, and its parents. + /// Caller should ensure transaction. + pub(crate) fn update_deck_stats( + &mut self, + today: u32, + usn: Usn, + input: pb::UpdateStatsIn, + ) -> Result<()> { + let did = input.deck_id.into(); + let mutator = |c: &mut DeckCommon| { + c.new_studied += input.new_delta; + c.review_studied += input.review_delta; + c.milliseconds_studied += input.millisecond_delta; + }; + if let Some(mut deck) = self.storage.get_deck(did)? { + self.update_deck_stats_single(today, usn, &mut deck, mutator)?; + for mut deck in self.storage.parent_decks(&deck)? { + self.update_deck_stats_single(today, usn, &mut deck, mutator)?; + } + } + Ok(()) + } + + /// Modify the deck's limits by adjusting the 'done today' count. + /// Positive values increase the limit, negative value decrease it. + /// Caller should ensure a transaction. + pub(crate) fn extend_limits( + &mut self, + today: u32, + usn: Usn, + did: DeckId, + new_delta: i32, + review_delta: i32, + ) -> Result<()> { + let mutator = |c: &mut DeckCommon| { + c.new_studied -= new_delta; + c.review_studied -= review_delta; + }; + if let Some(mut deck) = self.storage.get_deck(did)? { + self.update_deck_stats_single(today, usn, &mut deck, mutator)?; + for mut deck in self.storage.parent_decks(&deck)? { + self.update_deck_stats_single(today, usn, &mut deck, mutator)?; + } + for mut deck in self.storage.child_decks(&deck)? { + self.update_deck_stats_single(today, usn, &mut deck, mutator)?; + } + } + + Ok(()) + } + + fn update_deck_stats_single( + &mut self, + today: u32, + usn: Usn, + deck: &mut Deck, + mutator: F, + ) -> Result<()> + where + F: FnOnce(&mut DeckCommon), + { + let original = deck.clone(); + deck.reset_stats_if_day_changed(today); + mutator(&mut deck.common); + deck.set_modified(usn); + self.update_single_deck_undoable(deck, original) + } +}