use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::client::AnkiClient;
use crate::error::Result;
use crate::types::{Ease, Note};
#[derive(Debug)]
pub struct GuiActions<'a> {
pub(crate) client: &'a AnkiClient,
}
#[derive(Serialize)]
struct BrowseParams<'a> {
query: &'a str,
}
#[derive(Serialize)]
struct EditNoteParams {
note: i64,
}
#[derive(Serialize)]
struct AnswerCardParams {
ease: i32,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct DeckParams<'a> {
name: &'a str,
}
#[derive(Serialize)]
struct ImportParams<'a> {
path: &'a str,
}
#[derive(Serialize)]
struct SelectCardParams {
card: i64,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct AddNoteSetDataParams<'a> {
deck: &'a str,
model: &'a str,
fields: HashMap<&'a str, &'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
tags: Option<&'a [&'a str]>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CurrentCard {
pub card_id: i64,
pub note_id: i64,
pub deck_id: i64,
pub model_id: i64,
pub fields: serde_json::Value,
pub question: String,
pub answer: String,
pub deck_name: String,
pub model_name: String,
pub template_name: String,
pub buttons: Vec<i32>,
pub next_reviews: Vec<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ImportResult {
#[serde(default)]
pub found_notes: i64,
#[serde(default)]
pub imported_notes: i64,
}
impl<'a> GuiActions<'a> {
pub async fn browse(&self, query: &str) -> Result<Vec<i64>> {
self.client
.invoke("guiBrowse", BrowseParams { query })
.await
}
pub async fn selected_notes(&self) -> Result<Vec<i64>> {
self.client.invoke_without_params("guiSelectedNotes").await
}
pub async fn add_cards(&self, note: Note) -> Result<Option<i64>> {
self.client.invoke("guiAddCards", note).await
}
pub async fn edit_note(&self, note_id: i64) -> Result<()> {
self.client
.invoke_void("guiEditNote", EditNoteParams { note: note_id })
.await
}
pub async fn current_card(&self) -> Result<Option<CurrentCard>> {
self.client
.invoke_nullable_without_params("guiCurrentCard")
.await
}
pub async fn start_timer(&self) -> Result<bool> {
self.client.invoke_without_params("guiStartCardTimer").await
}
pub async fn show_question(&self) -> Result<bool> {
self.client.invoke_without_params("guiShowQuestion").await
}
pub async fn show_answer(&self) -> Result<bool> {
self.client.invoke_without_params("guiShowAnswer").await
}
pub async fn answer_card(&self, ease: Ease) -> Result<bool> {
self.client
.invoke("guiAnswerCard", AnswerCardParams { ease: ease.into() })
.await
}
pub async fn deck_overview(&self, name: &str) -> Result<bool> {
self.client
.invoke("guiDeckOverview", DeckParams { name })
.await
}
pub async fn deck_browser(&self) -> Result<bool> {
self.client.invoke_without_params("guiDeckBrowser").await
}
pub async fn deck_review(&self, name: &str) -> Result<bool> {
self.client
.invoke("guiDeckReview", DeckParams { name })
.await
}
pub async fn import_file(&self, path: &str) -> Result<ImportResult> {
self.client
.invoke("guiImportFile", ImportParams { path })
.await
}
pub async fn exit_anki(&self) -> Result<()> {
self.client.invoke_void("guiExitAnki", ()).await
}
pub async fn check_database(&self) -> Result<bool> {
self.client.invoke_without_params("guiCheckDatabase").await
}
pub async fn undo(&self) -> Result<()> {
self.client.invoke_void("guiUndo", ()).await
}
pub async fn select_card(&self, card_id: i64) -> Result<bool> {
self.client
.invoke("guiSelectCard", SelectCardParams { card: card_id })
.await
}
pub async fn add_note_set_data(
&self,
deck: &str,
model: &str,
fields: HashMap<&str, &str>,
tags: Option<&[&str]>,
) -> Result<()> {
self.client
.invoke_void(
"guiAddNoteSetData",
AddNoteSetDataParams {
deck,
model,
fields,
tags,
},
)
.await
}
pub async fn play_audio(&self, side: &str) -> Result<()> {
#[derive(Serialize)]
struct Params<'a> {
side: &'a str,
}
self.client
.invoke_void("guiPlayAudio", Params { side })
.await
}
pub async fn active_profile(&self) -> Result<String> {
self.client.invoke_without_params("getActiveProfile").await
}
}