use std::collections::HashMap;
use serde::Serialize;
use crate::client::AnkiClient;
use crate::error::Result;
use crate::types::{CanAddResult, Note, NoteInfo, NoteModTime};
#[derive(Debug)]
pub struct NoteActions<'a> {
pub(crate) client: &'a AnkiClient,
}
#[derive(Serialize)]
struct AddNoteParams {
note: Note,
}
#[derive(Serialize)]
struct FindNotesParams<'a> {
query: &'a str,
}
#[derive(Serialize)]
struct NotesInfoParams<'a> {
notes: &'a [i64],
}
#[derive(Serialize)]
struct UpdateNoteFieldsParams<'a> {
note: UpdateNoteFieldsInner<'a>,
}
#[derive(Serialize)]
struct UpdateNoteFieldsInner<'a> {
id: i64,
fields: &'a HashMap<String, String>,
}
#[derive(Serialize)]
struct DeleteNotesParams<'a> {
notes: &'a [i64],
}
#[derive(Serialize)]
struct AddNotesParams<'a> {
notes: &'a [Note],
}
#[derive(Serialize)]
struct CanAddNotesParams<'a> {
notes: &'a [Note],
}
#[derive(Serialize)]
struct TagsParams<'a> {
notes: &'a [i64],
tags: &'a str,
}
#[derive(Serialize)]
struct ReplaceTagsParams<'a> {
notes: &'a [i64],
tag_to_replace: &'a str,
replace_with_tag: &'a str,
}
#[derive(Serialize)]
struct ReplaceTagsAllParams<'a> {
tag_to_replace: &'a str,
replace_with_tag: &'a str,
}
#[derive(Serialize)]
struct UpdateNoteParams<'a> {
note: UpdateNoteInner<'a>,
}
#[derive(Serialize)]
struct UpdateNoteInner<'a> {
id: i64,
#[serde(skip_serializing_if = "Option::is_none")]
fields: Option<&'a HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
tags: Option<&'a [String]>,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct UpdateNoteModelParams<'a> {
note: i64,
model_name: &'a str,
#[serde(skip_serializing_if = "Option::is_none")]
field_map: Option<&'a HashMap<String, String>>,
}
#[derive(Serialize)]
struct UpdateNoteTagsParams<'a> {
note: i64,
tags: &'a [String],
}
impl<'a> NoteActions<'a> {
pub async fn add(&self, note: Note) -> Result<i64> {
self.client.invoke("addNote", AddNoteParams { note }).await
}
pub async fn find(&self, query: &str) -> Result<Vec<i64>> {
self.client
.invoke("findNotes", FindNotesParams { query })
.await
}
pub async fn info(&self, note_ids: &[i64]) -> Result<Vec<NoteInfo>> {
self.client
.invoke("notesInfo", NotesInfoParams { notes: note_ids })
.await
}
pub async fn update_fields(
&self,
note_id: i64,
fields: &HashMap<String, String>,
) -> Result<()> {
self.client
.invoke_void(
"updateNoteFields",
UpdateNoteFieldsParams {
note: UpdateNoteFieldsInner {
id: note_id,
fields,
},
},
)
.await
}
pub async fn delete(&self, note_ids: &[i64]) -> Result<()> {
self.client
.invoke_void("deleteNotes", DeleteNotesParams { notes: note_ids })
.await
}
pub async fn add_many(&self, notes: &[Note]) -> Result<Vec<Option<i64>>> {
self.client
.invoke("addNotes", AddNotesParams { notes })
.await
}
pub async fn can_add(&self, notes: &[Note]) -> Result<Vec<bool>> {
self.client
.invoke("canAddNotes", CanAddNotesParams { notes })
.await
}
pub async fn can_add_detailed(&self, notes: &[Note]) -> Result<Vec<CanAddResult>> {
self.client
.invoke("canAddNotesWithErrorDetail", CanAddNotesParams { notes })
.await
}
pub async fn get_tags(&self, note_id: i64) -> Result<Vec<String>> {
#[derive(Serialize)]
struct Params {
note: i64,
}
self.client
.invoke("getNoteTags", Params { note: note_id })
.await
}
pub async fn add_tags(&self, note_ids: &[i64], tags: &str) -> Result<()> {
self.client
.invoke_void(
"addTags",
TagsParams {
notes: note_ids,
tags,
},
)
.await
}
pub async fn remove_tags(&self, note_ids: &[i64], tags: &str) -> Result<()> {
self.client
.invoke_void(
"removeTags",
TagsParams {
notes: note_ids,
tags,
},
)
.await
}
pub async fn clear_unused_tags(&self) -> Result<()> {
self.client
.invoke_void("clearUnusedTags", serde_json::json!({}))
.await
}
pub async fn replace_tags(&self, note_ids: &[i64], old_tag: &str, new_tag: &str) -> Result<()> {
self.client
.invoke_void(
"replaceTags",
ReplaceTagsParams {
notes: note_ids,
tag_to_replace: old_tag,
replace_with_tag: new_tag,
},
)
.await
}
pub async fn replace_tags_all(&self, old_tag: &str, new_tag: &str) -> Result<()> {
self.client
.invoke_void(
"replaceTagsInAllNotes",
ReplaceTagsAllParams {
tag_to_replace: old_tag,
replace_with_tag: new_tag,
},
)
.await
}
pub async fn mod_time(&self, note_ids: &[i64]) -> Result<Vec<NoteModTime>> {
self.client
.invoke("notesModTime", NotesInfoParams { notes: note_ids })
.await
}
pub async fn remove_empty(&self) -> Result<()> {
self.client
.invoke_void("removeEmptyNotes", serde_json::json!({}))
.await
}
pub async fn update(
&self,
note_id: i64,
fields: Option<&HashMap<String, String>>,
tags: Option<&[String]>,
) -> Result<()> {
self.client
.invoke_void(
"updateNote",
UpdateNoteParams {
note: UpdateNoteInner {
id: note_id,
fields,
tags,
},
},
)
.await
}
pub async fn update_model(
&self,
note_id: i64,
model_name: &str,
field_map: Option<&HashMap<String, String>>,
) -> Result<()> {
self.client
.invoke_void(
"updateNoteModel",
UpdateNoteModelParams {
note: note_id,
model_name,
field_map,
},
)
.await
}
pub async fn set_tags(&self, note_id: i64, tags: &[String]) -> Result<()> {
self.client
.invoke_void(
"updateNoteTags",
UpdateNoteTagsParams {
note: note_id,
tags,
},
)
.await
}
pub async fn all_tags(&self) -> Result<Vec<String>> {
self.client.invoke("getTags", serde_json::json!({})).await
}
}