Create decks/stats.rs

This commit is contained in:
RumovZ 2021-04-15 20:06:16 +02:00
parent d2337e4cd3
commit 3138fccaca
2 changed files with 90 additions and 81 deletions

View file

@ -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<DeckConfId> {
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<F>(
&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)]

87
rslib/src/decks/stats.rs Normal file
View file

@ -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<F>(
&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)
}
}