use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::client::AnkiClient;
use crate::error::Result;
#[derive(Debug)]
pub struct StatisticsActions<'a> {
pub(crate) client: &'a AnkiClient,
}
#[derive(Serialize)]
struct CollectionStatsParams {
#[serde(rename = "wholeCollection")]
whole_collection: bool,
}
#[derive(Serialize)]
struct CardReviewsParams<'a> {
deck: &'a str,
#[serde(rename = "startID")]
start_id: i64,
}
#[derive(Serialize)]
struct ReviewsOfCardsParams<'a> {
cards: &'a [i64],
}
#[derive(Serialize)]
struct LatestReviewIdParams<'a> {
deck: &'a str,
}
#[derive(Serialize)]
struct InsertReviewsParams<'a> {
reviews: &'a [ReviewEntry],
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ReviewEntry {
pub card_id: i64,
#[serde(rename = "id")]
pub review_id: i64,
pub ease: i32,
#[serde(rename = "ivl")]
pub interval: i64,
#[serde(rename = "lastIvl")]
pub last_interval: i64,
pub factor: i64,
pub time: i64,
#[serde(rename = "type")]
pub review_type: i32,
}
impl ReviewEntry {
pub fn new(card_id: i64, review_id: i64) -> Self {
Self {
card_id,
review_id,
ease: 3,
interval: 1,
last_interval: -60,
factor: 2500,
time: 10000,
review_type: 1,
}
}
pub fn ease(mut self, ease: i32) -> Self {
self.ease = ease;
self
}
pub fn interval(mut self, interval: i64) -> Self {
self.interval = interval;
self
}
pub fn last_interval(mut self, interval: i64) -> Self {
self.last_interval = interval;
self
}
pub fn factor(mut self, factor: i64) -> Self {
self.factor = factor;
self
}
pub fn time(mut self, time: i64) -> Self {
self.time = time;
self
}
pub fn review_type(mut self, review_type: i32) -> Self {
self.review_type = review_type;
self
}
}
impl<'a> StatisticsActions<'a> {
pub async fn cards_reviewed_today(&self) -> Result<i64> {
self.client
.invoke_without_params("getNumCardsReviewedToday")
.await
}
pub async fn cards_reviewed_by_day(&self) -> Result<Vec<(String, i64)>> {
self.client
.invoke_without_params("getNumCardsReviewedByDay")
.await
}
pub async fn collection_html(&self, whole_collection: bool) -> Result<String> {
self.client
.invoke(
"getCollectionStatsHTML",
CollectionStatsParams { whole_collection },
)
.await
}
pub async fn reviews_since(
&self,
deck: &str,
start_id: i64,
) -> Result<HashMap<String, Vec<Vec<i64>>>> {
self.client
.invoke("cardReviews", CardReviewsParams { deck, start_id })
.await
}
pub async fn reviews_for_cards(
&self,
card_ids: &[i64],
) -> Result<HashMap<String, Vec<ReviewEntry>>> {
self.client
.invoke(
"getReviewsOfCards",
ReviewsOfCardsParams { cards: card_ids },
)
.await
}
pub async fn latest_review_id(&self, deck: &str) -> Result<i64> {
self.client
.invoke("getLatestReviewID", LatestReviewIdParams { deck })
.await
}
pub async fn insert(&self, reviews: &[ReviewEntry]) -> Result<()> {
self.client
.invoke_void("insertReviews", InsertReviewsParams { reviews })
.await
}
}